Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 64230a9

Browse files
author
Neil Conway
committed
Regression tests for large objects. Patch from Jeremy Drake.
1 parent f5f9577 commit 64230a9

File tree

4 files changed

+353
-3
lines changed

4 files changed

+353
-3
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
--
2+
-- Test large object support
3+
--
4+
5+
-- Load a file
6+
CREATE TABLE lotest_stash_values (loid oid, fd integer);
7+
-- lo_creat(mode integer) returns oid
8+
-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times
9+
-- returns the large object id
10+
INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42);
11+
12+
-- NOTE: large objects require transactions
13+
BEGIN;
14+
15+
-- lo_open(lobjId oid, mode integer) returns integer
16+
-- The mode parameter to lo_open uses two constants:
17+
-- INV_READ = 0x20000 = 2 * 16^4
18+
-- INV_WRITE = 0x40000 = 4 * 16^4
19+
-- The return value is a file descriptor-like value which remains valid for the
20+
-- transaction.
21+
UPDATE lotest_stash_values SET fd = lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
22+
23+
-- loread/lowrite names are wonky, different from other functions which are lo_*
24+
-- lowrite(fd integer, data bytea) returns integer
25+
-- the integer is the number of bytes written
26+
SELECT lowrite(fd, '
27+
Whose woods these are I think I know,
28+
His house is in the village though.
29+
He will not see me stopping here,
30+
To watch his woods fill up with snow.
31+
32+
My little horse must think it queer,
33+
To stop without a farmhouse near,
34+
Between the woods and frozen lake,
35+
The darkest evening of the year.
36+
37+
He gives his harness bells a shake,
38+
To ask if there is some mistake.
39+
The only other sound''s the sweep,
40+
Of easy wind and downy flake.
41+
42+
The woods are lovely, dark and deep,
43+
But I have promises to keep,
44+
And miles to go before I sleep,
45+
And miles to go before I sleep.
46+
47+
-- Robert Frost
48+
') FROM lotest_stash_values;
49+
50+
-- lo_close(fd integer) returns integer
51+
-- return value is 0 for success, or <0 for error (actually only -1, but...)
52+
SELECT lo_close(fd) FROM lotest_stash_values;
53+
54+
END;
55+
56+
-- Read out a portion
57+
BEGIN;
58+
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
59+
60+
-- lo_lseek(fd integer, offset integer, whence integer) returns integer
61+
-- offset is in bytes, whence is one of three values:
62+
-- SEEK_SET (= 0) meaning relative to beginning
63+
-- SEEK_CUR (= 1) meaning relative to current position
64+
-- SEEK_END (= 2) meaning relative to end (offset better be negative)
65+
-- returns current position in file
66+
SELECT lo_lseek(fd, 422, 0) FROM lotest_stash_values;
67+
68+
-- loread/lowrite names are wonky, different from other functions which are lo_*
69+
-- loread(fd integer, len integer) returns bytea
70+
SELECT loread(fd, 35) FROM lotest_stash_values;
71+
72+
SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values;
73+
74+
SELECT lowrite(fd, 'n') FROM lotest_stash_values;
75+
76+
SELECT lo_tell(fd) FROM lotest_stash_values;
77+
78+
SELECT lo_lseek(fd, -156, 2) FROM lotest_stash_values;
79+
80+
SELECT loread(fd, 35) FROM lotest_stash_values;
81+
82+
SELECT lo_close(fd) FROM lotest_stash_values;
83+
84+
END;
85+
86+
-- lo_unlink(lobjId oid) returns integer
87+
-- return value appears to always be 1
88+
SELECT lo_unlink(loid) from lotest_stash_values;
89+
90+
TRUNCATE lotest_stash_values;
91+
92+
INSERT INTO lotest_stash_values (loid) SELECT lo_import('@abs_srcdir@/data/tenk.data');
93+
94+
BEGIN;
95+
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
96+
97+
-- with the default BLKSZ, LOBLKSZ = 2048, so this positions us for a block
98+
-- edge case
99+
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
100+
101+
-- this should get half of the value from page 0 and half from page 1 of the
102+
-- large object
103+
SELECT loread(fd, 36) FROM lotest_stash_values;
104+
105+
SELECT lo_tell(fd) FROM lotest_stash_values;
106+
107+
SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
108+
109+
SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
110+
111+
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
112+
113+
SELECT loread(fd, 36) FROM lotest_stash_values;
114+
115+
SELECT lo_close(fd) FROM lotest_stash_values;
116+
END;
117+
118+
SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
119+
120+
\lo_import 'results/lotest.txt'
121+
122+
\set newloid :LASTOID
123+
124+
-- just make sure \lo_export does not barf
125+
\lo_export :newloid 'results/lotest2.txt'
126+
127+
-- This is a hack to test that export/import are reversible
128+
-- This uses knowledge about the inner workings of large object mechanism
129+
-- which should not be used outside it. This makes it a HACK
130+
SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values)
131+
EXCEPT
132+
SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid;
133+
134+
135+
SELECT lo_unlink(loid) FROM lotest_stash_values;
136+
\lo_unlink :newloid
137+
138+
TRUNCATE lotest_stash_values;
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
--
2+
-- Test large object support
3+
--
4+
-- Load a file
5+
CREATE TABLE lotest_stash_values (loid oid, fd integer);
6+
-- lo_creat(mode integer) returns oid
7+
-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times
8+
-- returns the large object id
9+
INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42);
10+
-- NOTE: large objects require transactions
11+
BEGIN;
12+
-- lo_open(lobjId oid, mode integer) returns integer
13+
-- The mode parameter to lo_open uses two constants:
14+
-- INV_READ = 0x20000 = 2 * 16^4
15+
-- INV_WRITE = 0x40000 = 4 * 16^4
16+
-- The return value is a file descriptor-like value which remains valid for the
17+
-- transaction.
18+
UPDATE lotest_stash_values SET fd = lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
19+
-- loread/lowrite names are wonky, different from other functions which are lo_*
20+
-- lowrite(fd integer, data bytea) returns integer
21+
-- the integer is the number of bytes written
22+
SELECT lowrite(fd, '
23+
Whose woods these are I think I know,
24+
His house is in the village though.
25+
He will not see me stopping here,
26+
To watch his woods fill up with snow.
27+
28+
My little horse must think it queer,
29+
To stop without a farmhouse near,
30+
Between the woods and frozen lake,
31+
The darkest evening of the year.
32+
33+
He gives his harness bells a shake,
34+
To ask if there is some mistake.
35+
The only other sound''s the sweep,
36+
Of easy wind and downy flake.
37+
38+
The woods are lovely, dark and deep,
39+
But I have promises to keep,
40+
And miles to go before I sleep,
41+
And miles to go before I sleep.
42+
43+
-- Robert Frost
44+
') FROM lotest_stash_values;
45+
lowrite
46+
---------
47+
578
48+
(1 row)
49+
50+
-- lo_close(fd integer) returns integer
51+
-- return value is 0 for success, or <0 for error (actually only -1, but...)
52+
SELECT lo_close(fd) FROM lotest_stash_values;
53+
lo_close
54+
----------
55+
0
56+
(1 row)
57+
58+
END;
59+
-- Read out a portion
60+
BEGIN;
61+
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
62+
-- lo_lseek(fd integer, offset integer, whence integer) returns integer
63+
-- offset is in bytes, whence is one of three values:
64+
-- SEEK_SET (= 0) meaning relative to beginning
65+
-- SEEK_CUR (= 1) meaning relative to current position
66+
-- SEEK_END (= 2) meaning relative to end (offset better be negative)
67+
-- returns current position in file
68+
SELECT lo_lseek(fd, 422, 0) FROM lotest_stash_values;
69+
lo_lseek
70+
----------
71+
422
72+
(1 row)
73+
74+
-- loread/lowrite names are wonky, different from other functions which are lo_*
75+
-- loread(fd integer, len integer) returns bytea
76+
SELECT loread(fd, 35) FROM lotest_stash_values;
77+
loread
78+
-------------------------------------
79+
The woods are lovely, dark and deep
80+
(1 row)
81+
82+
SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values;
83+
lo_lseek
84+
----------
85+
438
86+
(1 row)
87+
88+
SELECT lowrite(fd, 'n') FROM lotest_stash_values;
89+
lowrite
90+
---------
91+
1
92+
(1 row)
93+
94+
SELECT lo_tell(fd) FROM lotest_stash_values;
95+
lo_tell
96+
---------
97+
439
98+
(1 row)
99+
100+
SELECT lo_lseek(fd, -156, 2) FROM lotest_stash_values;
101+
lo_lseek
102+
----------
103+
422
104+
(1 row)
105+
106+
SELECT loread(fd, 35) FROM lotest_stash_values;
107+
loread
108+
-------------------------------------
109+
The woods are lonely, dark and deep
110+
(1 row)
111+
112+
SELECT lo_close(fd) FROM lotest_stash_values;
113+
lo_close
114+
----------
115+
0
116+
(1 row)
117+
118+
END;
119+
-- lo_unlink(lobjId oid) returns integer
120+
-- return value appears to always be 1
121+
SELECT lo_unlink(loid) from lotest_stash_values;
122+
lo_unlink
123+
-----------
124+
1
125+
(1 row)
126+
127+
TRUNCATE lotest_stash_values;
128+
INSERT INTO lotest_stash_values (loid) SELECT lo_import('@abs_srcdir@/data/tenk.data');
129+
BEGIN;
130+
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
131+
-- with the default BLKSZ, LOBLKSZ = 2048, so this positions us for a block
132+
-- edge case
133+
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
134+
lo_lseek
135+
----------
136+
2030
137+
(1 row)
138+
139+
-- this should get half of the value from page 0 and half from page 1 of the
140+
-- large object
141+
SELECT loread(fd, 36) FROM lotest_stash_values;
142+
loread
143+
-----------------------------------------------------------------
144+
AAA\011FBAAAA\011VVVVxx\0122513\01132\0111\0111\0113\01113\0111
145+
(1 row)
146+
147+
SELECT lo_tell(fd) FROM lotest_stash_values;
148+
lo_tell
149+
---------
150+
2066
151+
(1 row)
152+
153+
SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
154+
lo_lseek
155+
----------
156+
2040
157+
(1 row)
158+
159+
SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
160+
lowrite
161+
---------
162+
16
163+
(1 row)
164+
165+
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
166+
lo_lseek
167+
----------
168+
2030
169+
(1 row)
170+
171+
SELECT loread(fd, 36) FROM lotest_stash_values;
172+
loread
173+
-----------------------------------------------------
174+
AAA\011FBAAAAabcdefghijklmnop1\0111\0113\01113\0111
175+
(1 row)
176+
177+
SELECT lo_close(fd) FROM lotest_stash_values;
178+
lo_close
179+
----------
180+
0
181+
(1 row)
182+
183+
END;
184+
SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
185+
lo_export
186+
-----------
187+
1
188+
(1 row)
189+
190+
\lo_import 'results/lotest.txt'
191+
\set newloid :LASTOID
192+
-- just make sure \lo_export does not barf
193+
\lo_export :newloid 'results/lotest2.txt'
194+
-- This is a hack to test that export/import are reversible
195+
-- This uses knowledge about the inner workings of large object mechanism
196+
-- which should not be used outside it. This makes it a HACK
197+
SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values)
198+
EXCEPT
199+
SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid;
200+
pageno | data
201+
--------+------
202+
(0 rows)
203+
204+
SELECT lo_unlink(loid) FROM lotest_stash_values;
205+
lo_unlink
206+
-----------
207+
1
208+
(1 row)
209+
210+
\lo_unlink :newloid
211+
TRUNCATE lotest_stash_values;

src/test/regress/parallel_schedule

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ----------
22
# The first group of parallel test
3-
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.36 2006/12/21 16:05:16 petere Exp $
3+
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.37 2007/01/20 17:15:43 neilc Exp $
44
# ----------
55
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric
66

@@ -75,7 +75,7 @@ test: select_views portals_p2 rules foreign_key cluster dependency guc
7575
# The sixth group of parallel test
7676
# ----------
7777
# "plpgsql" cannot run concurrently with "rules"
78-
test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning xml
78+
test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject xml
7979

8080
# run stats by itself because its delay may be insufficient under heavy load
8181
test: stats

src/test/regress/serial_schedule

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.34 2006/12/21 16:05:16 petere Exp $
1+
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.35 2007/01/20 17:15:43 neilc Exp $
22
# This should probably be in an order similar to parallel_schedule.
33
test: boolean
44
test: char
@@ -102,6 +102,7 @@ test: sequence
102102
test: polymorphism
103103
test: rowtypes
104104
test: returning
105+
test: largeobject
105106
test: xml
106107
test: stats
107108
test: tablespace

0 commit comments

Comments
 (0)