Regression tests for large objects. Patch from Jeremy Drake.
This commit is contained in:
parent
f5f9577e50
commit
64230a9f28
138
src/test/regress/input/largeobject.source
Normal file
138
src/test/regress/input/largeobject.source
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
--
|
||||||
|
-- Test large object support
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Load a file
|
||||||
|
CREATE TABLE lotest_stash_values (loid oid, fd integer);
|
||||||
|
-- lo_creat(mode integer) returns oid
|
||||||
|
-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times
|
||||||
|
-- returns the large object id
|
||||||
|
INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42);
|
||||||
|
|
||||||
|
-- NOTE: large objects require transactions
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- lo_open(lobjId oid, mode integer) returns integer
|
||||||
|
-- The mode parameter to lo_open uses two constants:
|
||||||
|
-- INV_READ = 0x20000 = 2 * 16^4
|
||||||
|
-- INV_WRITE = 0x40000 = 4 * 16^4
|
||||||
|
-- The return value is a file descriptor-like value which remains valid for the
|
||||||
|
-- transaction.
|
||||||
|
UPDATE lotest_stash_values SET fd = lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
|
||||||
|
|
||||||
|
-- loread/lowrite names are wonky, different from other functions which are lo_*
|
||||||
|
-- lowrite(fd integer, data bytea) returns integer
|
||||||
|
-- the integer is the number of bytes written
|
||||||
|
SELECT lowrite(fd, '
|
||||||
|
Whose woods these are I think I know,
|
||||||
|
His house is in the village though.
|
||||||
|
He will not see me stopping here,
|
||||||
|
To watch his woods fill up with snow.
|
||||||
|
|
||||||
|
My little horse must think it queer,
|
||||||
|
To stop without a farmhouse near,
|
||||||
|
Between the woods and frozen lake,
|
||||||
|
The darkest evening of the year.
|
||||||
|
|
||||||
|
He gives his harness bells a shake,
|
||||||
|
To ask if there is some mistake.
|
||||||
|
The only other sound''s the sweep,
|
||||||
|
Of easy wind and downy flake.
|
||||||
|
|
||||||
|
The woods are lovely, dark and deep,
|
||||||
|
But I have promises to keep,
|
||||||
|
And miles to go before I sleep,
|
||||||
|
And miles to go before I sleep.
|
||||||
|
|
||||||
|
-- Robert Frost
|
||||||
|
') FROM lotest_stash_values;
|
||||||
|
|
||||||
|
-- lo_close(fd integer) returns integer
|
||||||
|
-- return value is 0 for success, or <0 for error (actually only -1, but...)
|
||||||
|
SELECT lo_close(fd) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Read out a portion
|
||||||
|
BEGIN;
|
||||||
|
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
|
||||||
|
|
||||||
|
-- lo_lseek(fd integer, offset integer, whence integer) returns integer
|
||||||
|
-- offset is in bytes, whence is one of three values:
|
||||||
|
-- SEEK_SET (= 0) meaning relative to beginning
|
||||||
|
-- SEEK_CUR (= 1) meaning relative to current position
|
||||||
|
-- SEEK_END (= 2) meaning relative to end (offset better be negative)
|
||||||
|
-- returns current position in file
|
||||||
|
SELECT lo_lseek(fd, 422, 0) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
-- loread/lowrite names are wonky, different from other functions which are lo_*
|
||||||
|
-- loread(fd integer, len integer) returns bytea
|
||||||
|
SELECT loread(fd, 35) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lowrite(fd, 'n') FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_tell(fd) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, -156, 2) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT loread(fd, 35) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_close(fd) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- lo_unlink(lobjId oid) returns integer
|
||||||
|
-- return value appears to always be 1
|
||||||
|
SELECT lo_unlink(loid) from lotest_stash_values;
|
||||||
|
|
||||||
|
TRUNCATE lotest_stash_values;
|
||||||
|
|
||||||
|
INSERT INTO lotest_stash_values (loid) SELECT lo_import('@abs_srcdir@/data/tenk.data');
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
|
||||||
|
|
||||||
|
-- with the default BLKSZ, LOBLKSZ = 2048, so this positions us for a block
|
||||||
|
-- edge case
|
||||||
|
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
-- this should get half of the value from page 0 and half from page 1 of the
|
||||||
|
-- large object
|
||||||
|
SELECT loread(fd, 36) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_tell(fd) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT loread(fd, 36) FROM lotest_stash_values;
|
||||||
|
|
||||||
|
SELECT lo_close(fd) FROM lotest_stash_values;
|
||||||
|
END;
|
||||||
|
|
||||||
|
SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
|
||||||
|
|
||||||
|
\lo_import 'results/lotest.txt'
|
||||||
|
|
||||||
|
\set newloid :LASTOID
|
||||||
|
|
||||||
|
-- just make sure \lo_export does not barf
|
||||||
|
\lo_export :newloid 'results/lotest2.txt'
|
||||||
|
|
||||||
|
-- This is a hack to test that export/import are reversible
|
||||||
|
-- This uses knowledge about the inner workings of large object mechanism
|
||||||
|
-- which should not be used outside it. This makes it a HACK
|
||||||
|
SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values)
|
||||||
|
EXCEPT
|
||||||
|
SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid;
|
||||||
|
|
||||||
|
|
||||||
|
SELECT lo_unlink(loid) FROM lotest_stash_values;
|
||||||
|
\lo_unlink :newloid
|
||||||
|
|
||||||
|
TRUNCATE lotest_stash_values;
|
211
src/test/regress/output/largeobject.source
Normal file
211
src/test/regress/output/largeobject.source
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
--
|
||||||
|
-- Test large object support
|
||||||
|
--
|
||||||
|
-- Load a file
|
||||||
|
CREATE TABLE lotest_stash_values (loid oid, fd integer);
|
||||||
|
-- lo_creat(mode integer) returns oid
|
||||||
|
-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times
|
||||||
|
-- returns the large object id
|
||||||
|
INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42);
|
||||||
|
-- NOTE: large objects require transactions
|
||||||
|
BEGIN;
|
||||||
|
-- lo_open(lobjId oid, mode integer) returns integer
|
||||||
|
-- The mode parameter to lo_open uses two constants:
|
||||||
|
-- INV_READ = 0x20000 = 2 * 16^4
|
||||||
|
-- INV_WRITE = 0x40000 = 4 * 16^4
|
||||||
|
-- The return value is a file descriptor-like value which remains valid for the
|
||||||
|
-- transaction.
|
||||||
|
UPDATE lotest_stash_values SET fd = lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
|
||||||
|
-- loread/lowrite names are wonky, different from other functions which are lo_*
|
||||||
|
-- lowrite(fd integer, data bytea) returns integer
|
||||||
|
-- the integer is the number of bytes written
|
||||||
|
SELECT lowrite(fd, '
|
||||||
|
Whose woods these are I think I know,
|
||||||
|
His house is in the village though.
|
||||||
|
He will not see me stopping here,
|
||||||
|
To watch his woods fill up with snow.
|
||||||
|
|
||||||
|
My little horse must think it queer,
|
||||||
|
To stop without a farmhouse near,
|
||||||
|
Between the woods and frozen lake,
|
||||||
|
The darkest evening of the year.
|
||||||
|
|
||||||
|
He gives his harness bells a shake,
|
||||||
|
To ask if there is some mistake.
|
||||||
|
The only other sound''s the sweep,
|
||||||
|
Of easy wind and downy flake.
|
||||||
|
|
||||||
|
The woods are lovely, dark and deep,
|
||||||
|
But I have promises to keep,
|
||||||
|
And miles to go before I sleep,
|
||||||
|
And miles to go before I sleep.
|
||||||
|
|
||||||
|
-- Robert Frost
|
||||||
|
') FROM lotest_stash_values;
|
||||||
|
lowrite
|
||||||
|
---------
|
||||||
|
578
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- lo_close(fd integer) returns integer
|
||||||
|
-- return value is 0 for success, or <0 for error (actually only -1, but...)
|
||||||
|
SELECT lo_close(fd) FROM lotest_stash_values;
|
||||||
|
lo_close
|
||||||
|
----------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
END;
|
||||||
|
-- Read out a portion
|
||||||
|
BEGIN;
|
||||||
|
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
|
||||||
|
-- lo_lseek(fd integer, offset integer, whence integer) returns integer
|
||||||
|
-- offset is in bytes, whence is one of three values:
|
||||||
|
-- SEEK_SET (= 0) meaning relative to beginning
|
||||||
|
-- SEEK_CUR (= 1) meaning relative to current position
|
||||||
|
-- SEEK_END (= 2) meaning relative to end (offset better be negative)
|
||||||
|
-- returns current position in file
|
||||||
|
SELECT lo_lseek(fd, 422, 0) FROM lotest_stash_values;
|
||||||
|
lo_lseek
|
||||||
|
----------
|
||||||
|
422
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- loread/lowrite names are wonky, different from other functions which are lo_*
|
||||||
|
-- loread(fd integer, len integer) returns bytea
|
||||||
|
SELECT loread(fd, 35) FROM lotest_stash_values;
|
||||||
|
loread
|
||||||
|
-------------------------------------
|
||||||
|
The woods are lovely, dark and deep
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values;
|
||||||
|
lo_lseek
|
||||||
|
----------
|
||||||
|
438
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lowrite(fd, 'n') FROM lotest_stash_values;
|
||||||
|
lowrite
|
||||||
|
---------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_tell(fd) FROM lotest_stash_values;
|
||||||
|
lo_tell
|
||||||
|
---------
|
||||||
|
439
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, -156, 2) FROM lotest_stash_values;
|
||||||
|
lo_lseek
|
||||||
|
----------
|
||||||
|
422
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT loread(fd, 35) FROM lotest_stash_values;
|
||||||
|
loread
|
||||||
|
-------------------------------------
|
||||||
|
The woods are lonely, dark and deep
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_close(fd) FROM lotest_stash_values;
|
||||||
|
lo_close
|
||||||
|
----------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
END;
|
||||||
|
-- lo_unlink(lobjId oid) returns integer
|
||||||
|
-- return value appears to always be 1
|
||||||
|
SELECT lo_unlink(loid) from lotest_stash_values;
|
||||||
|
lo_unlink
|
||||||
|
-----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
TRUNCATE lotest_stash_values;
|
||||||
|
INSERT INTO lotest_stash_values (loid) SELECT lo_import('@abs_srcdir@/data/tenk.data');
|
||||||
|
BEGIN;
|
||||||
|
UPDATE lotest_stash_values SET fd=lo_open(loid, CAST((2 | 4) * 16^4 AS integer));
|
||||||
|
-- with the default BLKSZ, LOBLKSZ = 2048, so this positions us for a block
|
||||||
|
-- edge case
|
||||||
|
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
|
||||||
|
lo_lseek
|
||||||
|
----------
|
||||||
|
2030
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- this should get half of the value from page 0 and half from page 1 of the
|
||||||
|
-- large object
|
||||||
|
SELECT loread(fd, 36) FROM lotest_stash_values;
|
||||||
|
loread
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
AAA\011FBAAAA\011VVVVxx\0122513\01132\0111\0111\0113\01113\0111
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_tell(fd) FROM lotest_stash_values;
|
||||||
|
lo_tell
|
||||||
|
---------
|
||||||
|
2066
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
|
||||||
|
lo_lseek
|
||||||
|
----------
|
||||||
|
2040
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
|
||||||
|
lowrite
|
||||||
|
---------
|
||||||
|
16
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
|
||||||
|
lo_lseek
|
||||||
|
----------
|
||||||
|
2030
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT loread(fd, 36) FROM lotest_stash_values;
|
||||||
|
loread
|
||||||
|
-----------------------------------------------------
|
||||||
|
AAA\011FBAAAAabcdefghijklmnop1\0111\0113\01113\0111
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lo_close(fd) FROM lotest_stash_values;
|
||||||
|
lo_close
|
||||||
|
----------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
END;
|
||||||
|
SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
|
||||||
|
lo_export
|
||||||
|
-----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\lo_import 'results/lotest.txt'
|
||||||
|
\set newloid :LASTOID
|
||||||
|
-- just make sure \lo_export does not barf
|
||||||
|
\lo_export :newloid 'results/lotest2.txt'
|
||||||
|
-- This is a hack to test that export/import are reversible
|
||||||
|
-- This uses knowledge about the inner workings of large object mechanism
|
||||||
|
-- which should not be used outside it. This makes it a HACK
|
||||||
|
SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values)
|
||||||
|
EXCEPT
|
||||||
|
SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid;
|
||||||
|
pageno | data
|
||||||
|
--------+------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT lo_unlink(loid) FROM lotest_stash_values;
|
||||||
|
lo_unlink
|
||||||
|
-----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\lo_unlink :newloid
|
||||||
|
TRUNCATE lotest_stash_values;
|
@ -1,6 +1,6 @@
|
|||||||
# ----------
|
# ----------
|
||||||
# The first group of parallel test
|
# The first group of parallel test
|
||||||
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.36 2006/12/21 16:05:16 petere Exp $
|
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.37 2007/01/20 17:15:43 neilc Exp $
|
||||||
# ----------
|
# ----------
|
||||||
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric
|
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ test: select_views portals_p2 rules foreign_key cluster dependency guc
|
|||||||
# The sixth group of parallel test
|
# The sixth group of parallel test
|
||||||
# ----------
|
# ----------
|
||||||
# "plpgsql" cannot run concurrently with "rules"
|
# "plpgsql" cannot run concurrently with "rules"
|
||||||
test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning xml
|
test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject xml
|
||||||
|
|
||||||
# run stats by itself because its delay may be insufficient under heavy load
|
# run stats by itself because its delay may be insufficient under heavy load
|
||||||
test: stats
|
test: stats
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.34 2006/12/21 16:05:16 petere Exp $
|
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.35 2007/01/20 17:15:43 neilc Exp $
|
||||||
# This should probably be in an order similar to parallel_schedule.
|
# This should probably be in an order similar to parallel_schedule.
|
||||||
test: boolean
|
test: boolean
|
||||||
test: char
|
test: char
|
||||||
@ -102,6 +102,7 @@ test: sequence
|
|||||||
test: polymorphism
|
test: polymorphism
|
||||||
test: rowtypes
|
test: rowtypes
|
||||||
test: returning
|
test: returning
|
||||||
|
test: largeobject
|
||||||
test: xml
|
test: xml
|
||||||
test: stats
|
test: stats
|
||||||
test: tablespace
|
test: tablespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user