-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdomain.sql
More file actions
183 lines (159 loc) · 4.41 KB
/
Copy pathdomain.sql
File metadata and controls
183 lines (159 loc) · 4.41 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
-- Test the fact that the domain constraint is being applied
-- in multiple situations.
DROP DOMAIN IF EXISTS i5 CASCADE;
DROP DOMAIN IF EXISTS i4 CASCADE;
DROP DOMAIN IF EXISTS i3 CASCADE;
DROP DOMAIN IF EXISTS i2 CASCADE;
DROP DOMAIN IF EXISTS i1 CASCADE;
-- No constraint, simple alias.
CREATE DOMAIN i1 AS int4;
-- NOT NULL restriction
CREATE DOMAIN i2 AS i1 NOT NULL;
-- Must be greater than or equal to zero
CREATE DOMAIN i3 AS i2 CHECK (VALUE >= 0);
-- And must be less than or equal to zero(only one possible value)
CREATE DOMAIN i4 AS i3 CHECK (VALUE <= 0);
-- And must not be zero(no possible values)
CREATE DOMAIN i5 AS i4 CHECK (VALUE != 0);
-- The point of these domains is to check that the all the basetype
-- constraints are actually being tested when a check() is performed
CREATE OR REPLACE FUNCTION test_domain_instantiation() RETURNS text LANGUAGE python AS
$python$
import Postgres
# Just pack everything in here.
# It's a bit unittest-ish, but very convenient for the test we're doing.
rt = Postgres.Type(Postgres.CONST['REGTYPEOID'])
# load out of order, just in case the implementation
# has some issue wrt fully resolving supers.
i5 = Postgres.Type(rt('i5'))
i2 = Postgres.Type(rt('i2'))
i1 = Postgres.Type(rt('i1'))
i3 = Postgres.Type(rt('i3'))
i4 = Postgres.Type(rt('i4'))
int4 = Postgres.Type(rt('int4'))
# sanity check; proper inheritance is happening, yes?
domains = [
(i5,i4),
(i4,i3),
(i3,i2),
(i2,i1),
(i1,int4),
(int4,Postgres.Object),
]
for sub,sup in domains:
assert(issubclass(sub,sup))
data = [
(int4, [
# just way too big
234324234324234324234234324234, -123123223742348742384237832,
-123, 0, 234,
None
]),
(i1, [
# ditto
234324234324234324234234324234, -123123223742348742384237832,
-123, 0, 234,
None
]),
(i2, [
234324234324234324234234324234, -123123223742348742384237832,
-123, 0, 234,
None,
]),
(i3, [
# fail on -1
-1, 0, 123,
None
]),
(i4, [
# fail on -1 and 1234
-2, 0, 1234,
None
]),
(i5, [
# fail on -1, 0, and 12345
-3, 0, 12345,
None
]),
]
def main():
output = "\n"
for typ, dl in data:
output += "\n" + typ.__name__ + ":\n"
for x in dl:
try:
with xact():
r = typ(x)
typ.check(r)
output += " success for: '" + str(x) + "' -> '" + str(r) + "' (" + type(r).__name__ + ")\n"
except Postgres.Exception as e:
output += " fail for: '" + str(x) + "' [" + str(e.code) + ": " + str(e.message) + "]\n"
except Exception as e:
output += " fail for: '" + str(x) + "' [" + str(e) + "]\n"
return output
$python$;
SELECT test_domain_instantiation();
-- This test is validating that domain casting functionality
-- is available. Specifically, no Postgres CAST is actually
-- being used. Rather, the relationship between the types should
-- be identified and used to merely perform a datumCopy
CREATE OR REPLACE FUNCTION test_domain_casts() RETURNS text LANGUAGE python AS
$python$
import Postgres
# Just pack everything in here.
# It's a bit unittest-ish, but very convenient for the test we're doing.
rt = Postgres.Type(Postgres.CONST['REGTYPEOID'])
int4 = Postgres.Type(rt('int4'))
i1 = Postgres.Type(rt('i1'))
i2 = Postgres.Type(rt('i2'))
i3 = Postgres.Type(rt('i3'))
i4 = Postgres.Type(rt('i4'))
i5 = Postgres.Type(rt('i5'))
data = [
(int4, [
int4(-123), int4(0), int4(234), int4(None)
]),
(i1, [
i1(-123), i1(0), i1(234), i1(None)
]),
(i2, [
i2(-123), i2(0), i2(234),
]),
(i3, [
i3(0), i3(123),
]),
(i4, [i4(0),]),
(i5, []),
]
types = (int4, i1, i2, i3, i4, i5)
def main():
output = "\n"
for typ, dl in data:
output += "\n" + typ.__name__ + ":\n"
for x in dl:
for desttyp in types:
try:
with xact():
r = desttyp(x)
desttyp.check(r)
assert r == x
output += " success for: '" + str(x) + "' -> (" + desttyp.__name__ + ")\n"
except Postgres.Exception as e:
output += " fail for: '" + str(x) + "' -> " + desttyp.__name__ + " [" + str(e.code) + ": " + str(e.message) + "]\n"
except Exception as e:
output += " fail for: '" + str(x) + "' -> " + desttyp.__name__ + " [" + str(e) + "]\n"
return output
$python$;
SELECT test_domain_casts();
CREATE OR REPLACE FUNCTION
check_on_srf(OUT a i1, OUT i i2, OUT j i3, OUT j2 i4) RETURNS SETOF record
LANGUAGE python AS
$python$
def main():
# last one is invalid
return ((432, 432, 0, -1),)
$python$;
-- python is an untrusted language, the user must explicitly
-- check domain values.
SELECT check_on_srf();
SELECT * FROM check_on_srf();