Skip to content

Commit 5acde74

Browse files
committed
Add alternate result file for large object tests to handle Windows line ends.
1 parent c0aa506 commit 5acde74

File tree

1 file changed

+275
-0
lines changed

1 file changed

+275
-0
lines changed
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
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
15+
-- INV_WRITE = 0x40000
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(x'20000' | x'40000' 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(x'20000' | x'40000' 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+
-- Test truncation.
120+
BEGIN;
121+
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
122+
SELECT lo_truncate(fd, 10) FROM lotest_stash_values;
123+
lo_truncate
124+
-------------
125+
0
126+
(1 row)
127+
128+
SELECT loread(fd, 15) FROM lotest_stash_values;
129+
loread
130+
---------------
131+
\012Whose woo
132+
(1 row)
133+
134+
SELECT lo_truncate(fd, 10000) FROM lotest_stash_values;
135+
lo_truncate
136+
-------------
137+
0
138+
(1 row)
139+
140+
SELECT loread(fd, 10) FROM lotest_stash_values;
141+
loread
142+
------------------------------------------
143+
\000\000\000\000\000\000\000\000\000\000
144+
(1 row)
145+
146+
SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values;
147+
lo_lseek
148+
----------
149+
10000
150+
(1 row)
151+
152+
SELECT lo_tell(fd) FROM lotest_stash_values;
153+
lo_tell
154+
---------
155+
10000
156+
(1 row)
157+
158+
SELECT lo_truncate(fd, 5000) FROM lotest_stash_values;
159+
lo_truncate
160+
-------------
161+
0
162+
(1 row)
163+
164+
SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values;
165+
lo_lseek
166+
----------
167+
5000
168+
(1 row)
169+
170+
SELECT lo_tell(fd) FROM lotest_stash_values;
171+
lo_tell
172+
---------
173+
5000
174+
(1 row)
175+
176+
SELECT lo_close(fd) FROM lotest_stash_values;
177+
lo_close
178+
----------
179+
0
180+
(1 row)
181+
182+
END;
183+
-- lo_unlink(lobjId oid) returns integer
184+
-- return value appears to always be 1
185+
SELECT lo_unlink(loid) from lotest_stash_values;
186+
lo_unlink
187+
-----------
188+
1
189+
(1 row)
190+
191+
TRUNCATE lotest_stash_values;
192+
INSERT INTO lotest_stash_values (loid) SELECT lo_import('@abs_srcdir@/data/tenk.data');
193+
BEGIN;
194+
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
195+
-- with the default BLKSZ, LOBLKSZ = 2048, so this positions us for a block
196+
-- edge case
197+
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
198+
lo_lseek
199+
----------
200+
2030
201+
(1 row)
202+
203+
-- this should get half of the value from page 0 and half from page 1 of the
204+
-- large object
205+
SELECT loread(fd, 36) FROM lotest_stash_values;
206+
loread
207+
--------------------------------------------------------------
208+
44\011144\0111144\0114144\0119144\01188\01189\011SNAAAA\011F
209+
(1 row)
210+
211+
SELECT lo_tell(fd) FROM lotest_stash_values;
212+
lo_tell
213+
---------
214+
2066
215+
(1 row)
216+
217+
SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
218+
lo_lseek
219+
----------
220+
2040
221+
(1 row)
222+
223+
SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
224+
lowrite
225+
---------
226+
16
227+
(1 row)
228+
229+
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
230+
lo_lseek
231+
----------
232+
2030
233+
(1 row)
234+
235+
SELECT loread(fd, 36) FROM lotest_stash_values;
236+
loread
237+
--------------------------------------------------
238+
44\011144\011114abcdefghijklmnop9\011SNAAAA\011F
239+
(1 row)
240+
241+
SELECT lo_close(fd) FROM lotest_stash_values;
242+
lo_close
243+
----------
244+
0
245+
(1 row)
246+
247+
END;
248+
SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
249+
lo_export
250+
-----------
251+
1
252+
(1 row)
253+
254+
\lo_import 'results/lotest.txt'
255+
\set newloid :LASTOID
256+
-- just make sure \lo_export does not barf
257+
\lo_export :newloid 'results/lotest2.txt'
258+
-- This is a hack to test that export/import are reversible
259+
-- This uses knowledge about the inner workings of large object mechanism
260+
-- which should not be used outside it. This makes it a HACK
261+
SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values)
262+
EXCEPT
263+
SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid;
264+
pageno | data
265+
--------+------
266+
(0 rows)
267+
268+
SELECT lo_unlink(loid) FROM lotest_stash_values;
269+
lo_unlink
270+
-----------
271+
1
272+
(1 row)
273+
274+
\lo_unlink :newloid
275+
TRUNCATE lotest_stash_values;

0 commit comments

Comments
 (0)