]> granicus.if.org Git - postgresql/commitdiff
Regression tests for large objects. Patch from Jeremy Drake.
authorNeil Conway <neilc@samurai.com>
Sat, 20 Jan 2007 17:15:44 +0000 (17:15 +0000)
committerNeil Conway <neilc@samurai.com>
Sat, 20 Jan 2007 17:15:44 +0000 (17:15 +0000)
src/test/regress/input/largeobject.source [new file with mode: 0644]
src/test/regress/output/largeobject.source [new file with mode: 0644]
src/test/regress/parallel_schedule
src/test/regress/serial_schedule

diff --git a/src/test/regress/input/largeobject.source b/src/test/regress/input/largeobject.source
new file mode 100644 (file)
index 0000000..e89ce02
--- /dev/null
@@ -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 (file)
index 0000000..6d6e5cd
--- /dev/null
@@ -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;
index a8f9ee09b591db09427c85f179e14c801294673c..c2e53fb5c351473088d3b65c8f48ecb6c75e3693 100644 (file)
@@ -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
index 1fa94fadc0417d7ba4005300097bcb1cac384ad0..4c1c63c62e08c9e3fafa19419934a1093ebfa04e 100644 (file)
@@ -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