-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfunctions-redshift.sql
127 lines (105 loc) · 5.56 KB
/
functions-redshift.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
creates functions based on redshift functions
*/
set search_path to public;
create or replace function to_part (pos int, data text, pos_part int, bits int) returns text immutable
as $$
select substring($2, $1 + 65 - ($3 + 1) * ($4/8)*2, ($4/8)*2)
$$ language sql;
create or replace function to_positive (pos int, data text, pos_part int, bits int) returns bigint immutable
as $$
select strtol(to_part($1, $2, $3, $4), 16)
$$ language sql;
create or replace function to_uint8 (pos int, data text) returns bigint immutable
as $$
select to_positive($1, $2, 0, 8)
$$ language sql;
create or replace function to_uint16 (pos int, data text) returns bigint immutable
as $$
select to_positive($1, $2, 0, 16)
$$ language sql;
create or replace function to_uint32 (pos int, data text) returns bigint immutable
as $$
select to_positive($1, $2, 0, 32)
$$ language sql;
create or replace function to_uint64 (pos int, data text) returns bigint immutable
as $$
select to_positive($1, $2, 0, 64)
$$ language sql;
create or replace function to_binary (pos int, data text, pos_part int, bits int) returns varbyte immutable
as $$
select from_hex(to_part($1, $2, $3, $4))
$$ language sql;
create or replace function is_positive (pos int, data text, pos_part int, bits int) returns bool immutable
as $$
select getbit(to_binary($1, $2, $3, $4), $4 - 1) = 0
$$ language sql;
create or replace function to_negative (pos int, data text, pos_part int, bits int) returns bigint immutable
as $$
select ~strtol(to_hex(~to_binary($1, $2, $3, $4)), 16) -- todo forgot to add 1 to binary inverse?
$$ language sql;
create or replace function to_int32 (pos int, data text) returns bigint immutable
as $$
select case when is_positive($1, $2, 0, 32) then to_positive($1, $2, 0, 32) else to_negative($1, $2, 0, 32) end;
$$ language sql;
create or replace function to_int64 (pos int, data text) returns bigint immutable
as $$
select case when is_positive($1, $2, 0, 64) then to_positive($1, $2, 0, 64) else to_negative($1, $2, 0, 64) end;
$$ language sql;
create or replace function to_uint128 (pos int, data text) returns dec immutable
as $$
select to_positive($1, $2, 3, 32)::dec*4294967296*4294967296*4294967296 + to_positive($1, $2, 2, 32)::dec*4294967296*4294967296 + to_positive($1, $2, 1, 32)::dec*4294967296 + to_positive($1, $2, 0, 32)::dec
$$ language sql;
create or replace function to_uint32_array (pos int, data text) returns super immutable
as $$
select array(to_positive($1, $2, 7, 32),
to_positive($1, $2, 6, 32),
to_positive($1, $2, 5, 32),
to_positive($1, $2, 4, 32),
to_positive($1, $2, 3, 32),
to_positive($1, $2, 2, 32),
to_positive($1, $2, 1, 32),
to_positive($1, $2, 0, 32))
$$ language sql;
create or replace function to_uint64_array (pos int, data text) returns super immutable
as $$
select array(to_positive($1, $2, 7, 32)::dec*4294967296 + to_positive($1, $2, 6, 32),
to_positive($1, $2, 5, 32)::dec*4294967296 + to_positive($1, $2, 4, 32),
to_positive($1, $2, 3, 32)::dec*4294967296 + to_positive($1, $2, 2, 32),
to_positive($1, $2, 1, 32)::dec*4294967296 + to_positive($1, $2, 0, 32))
$$ language sql;
create or replace function to_uint128_array (pos int, data text) returns super immutable
as $$
select array(to_positive($1, $2, 7, 32)::dec*4294967296*4294967296*4294967296 + to_positive($1, $2, 6, 32)::dec*4294967296*4294967296 + to_positive($1, $2, 5, 32)::dec*4294967296 + to_positive($1, $2, 4, 32),
to_positive($1, $2, 3, 32)::dec*4294967296*4294967296*4294967296 + to_positive($1, $2, 2, 32)::dec*4294967296*4294967296 + to_positive($1, $2, 1, 32)::dec*4294967296 + to_positive($1, $2, 0, 32))
$$ language sql;
create or replace function has_part (pos int, data text, pos_part int, bits int) returns bool immutable
as $$
select length(ltrim(to_part($1, $2, $3, $4), '0')) > 0
$$ language sql;
/*create or replace function can_overflow (pos int, data text) returns bool immutable
as $$
select case
when has_part($1, $2, 3, 32) then
to_positive($1, $2, 3, 32) > 1262177448 or log(to_positive($1, $2, 3, 32)::dec*4294967296*4294967296*4294967296::float) + to_positive($1, $2, 2, 32)::dec*4294967296*4294967296 / (to_positive($1, $2, 3, 32)::dec*4294967296*4294967296*4294967296) > 38
when has_part($1, $2, 7, 32) then
to_positive($1, $2, 7, 32) > 1262177448 or log(to_positive($1, $2, 7, 32)::dec*4294967296*4294967296*4294967296::float) + to_positive($1, $2, 6, 32)::dec*4294967296*4294967296 / (to_positive($1, $2, 7, 32)::dec*4294967296*4294967296*4294967296) > 38
else false end;
$$ language sql;*/
create or replace function can_overflow (pos int, data text) returns bool immutable
as $$
select (has_part($1, $2, 7, 32) and (to_positive($1, $2, 7, 32) > 1262177448 or ceiling(log(to_positive($1, $2, 7, 32)::dec*4294967296*4294967296*4294967296::float)) >= 38))
or (has_part($1, $2, 3, 32) and (to_positive($1, $2, 3, 32) > 1262177448 or ceiling(log(to_positive($1, $2, 3, 32)::dec*4294967296*4294967296*4294967296::float)) >= 38))
$$ language sql;
create or replace function to_uint128_array_or_null (pos int, data text) returns super immutable
as $$
select case when can_overflow($1, $2) then null else to_uint128_array($1, $2) end
$$ language sql;
create or replace function to_decimal (pos int, data text) returns decimal immutable
as $$
select case when can_overflow($1, $2) then null else to_uint128($1, $2) end
$$ language sql;
create or replace function to_uint256 (pos int, data text) returns super immutable
as $$
select to_uint128_array_or_null($1, $2)
$$ language sql;