From: Neil Conway Date: Sat, 20 Jan 2007 17:15:44 +0000 (+0000) Subject: Regression tests for large objects. Patch from Jeremy Drake. X-Git-Tag: REL8_3_BETA1~1484 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64230a9f28e607110ee1e97eeb1e7f615e66eb78;p=postgresql Regression tests for large objects. Patch from Jeremy Drake. --- diff --git a/src/test/regress/input/largeobject.source b/src/test/regress/input/largeobject.source new file mode 100644 index 0000000000..e89ce02fa9 --- /dev/null +++ b/src/test/regress/input/largeobject.source @@ -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; diff --git a/src/test/regress/output/largeobject.source b/src/test/regress/output/largeobject.source new file mode 100644 index 0000000000..6d6e5cd24c --- /dev/null +++ b/src/test/regress/output/largeobject.source @@ -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; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index a8f9ee09b5..c2e53fb5c3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -1,6 +1,6 @@ # ---------- # 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 @@ -75,7 +75,7 @@ test: select_views portals_p2 rules foreign_key cluster dependency guc # The sixth group of parallel test # ---------- # "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 test: stats diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 1fa94fadc0..4c1c63c62e 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -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. test: boolean test: char @@ -102,6 +102,7 @@ test: sequence test: polymorphism test: rowtypes test: returning +test: largeobject test: xml test: stats test: tablespace