summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael P2011-12-20 07:58:43 +0000
committerMichael P2011-12-20 07:58:43 +0000
commit295aa93245d68ff0d7038ec6de931ee777ae03a6 (patch)
tree43c0bdb630b9d6c7921dfc4fa4c66dd29f5f4bd1 /src
parent25db704c09aedb8cf2015d88739cc213fcec2635 (diff)
Block the usage of large objects
Regressions are modified in consequence.
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/be-fsstubs.c105
-rw-r--r--src/test/regress/output/largeobject_3.source264
2 files changed, 369 insertions, 0 deletions
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index 155385f0b9..070e1451e8 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -101,6 +101,13 @@ lo_open(PG_FUNCTION_ARGS)
LargeObjectDesc *lobjDesc;
int fd;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
#if FSDB
elog(DEBUG4, "lo_open(%u,%d)", lobjId, mode);
#endif
@@ -127,6 +134,13 @@ lo_close(PG_FUNCTION_ARGS)
{
int32 fd = PG_GETARG_INT32(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -157,6 +171,13 @@ lo_read(int fd, char *buf, int len)
{
int status;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -183,6 +204,13 @@ lo_write(int fd, const char *buf, int len)
{
int status;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -219,6 +247,13 @@ lo_lseek(PG_FUNCTION_ARGS)
int32 whence = PG_GETARG_INT32(2);
int status;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -234,6 +269,13 @@ lo_creat(PG_FUNCTION_ARGS)
{
Oid lobjId;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
/*
* We don't actually need to store into fscxt, but create it anyway to
* ensure that AtEOXact_LargeObject knows there is state to clean up
@@ -250,6 +292,13 @@ lo_create(PG_FUNCTION_ARGS)
{
Oid lobjId = PG_GETARG_OID(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
/*
* We don't actually need to store into fscxt, but create it anyway to
* ensure that AtEOXact_LargeObject knows there is state to clean up
@@ -266,6 +315,13 @@ lo_tell(PG_FUNCTION_ARGS)
{
int32 fd = PG_GETARG_INT32(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -279,6 +335,13 @@ lo_unlink(PG_FUNCTION_ARGS)
{
Oid lobjId = PG_GETARG_OID(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
/* Must be owner of the largeobject */
if (!lo_compat_privileges &&
!pg_largeobject_ownercheck(lobjId, GetUserId()))
@@ -322,6 +385,13 @@ loread(PG_FUNCTION_ARGS)
bytea *retval;
int totalread;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (len < 0)
len = 0;
@@ -340,6 +410,13 @@ lowrite(PG_FUNCTION_ARGS)
int bytestowrite;
int totalwritten;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
bytestowrite = VARSIZE(wbuf) - VARHDRSZ;
totalwritten = lo_write(fd, VARDATA(wbuf), bytestowrite);
PG_RETURN_INT32(totalwritten);
@@ -358,6 +435,13 @@ lo_import(PG_FUNCTION_ARGS)
{
text *filename = PG_GETARG_TEXT_PP(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
PG_RETURN_OID(lo_import_internal(filename, InvalidOid));
}
@@ -371,6 +455,13 @@ lo_import_with_oid(PG_FUNCTION_ARGS)
text *filename = PG_GETARG_TEXT_PP(0);
Oid oid = PG_GETARG_OID(1);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
PG_RETURN_OID(lo_import_internal(filename, oid));
}
@@ -451,6 +542,13 @@ lo_export(PG_FUNCTION_ARGS)
LargeObjectDesc *lobj;
mode_t oumask;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
#ifndef ALLOW_DANGEROUS_LO_FUNCTIONS
if (!superuser())
ereport(ERROR,
@@ -513,6 +611,13 @@ lo_truncate(PG_FUNCTION_ARGS)
int32 fd = PG_GETARG_INT32(0);
int32 len = PG_GETARG_INT32(1);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
diff --git a/src/test/regress/output/largeobject_3.source b/src/test/regress/output/largeobject_3.source
new file mode 100644
index 0000000000..5c350f37a4
--- /dev/null
+++ b/src/test/regress/output/largeobject_3.source
@@ -0,0 +1,264 @@
+--
+-- Test large object support
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- Load a file
+CREATE TABLE lotest_stash_values (loid oid, junk integer, 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) VALUES( lo_creat(42) );
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+-- 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
+-- INV_WRITE = 0x40000
+-- 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(x'20000' | x'40000' 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
+---------
+(0 rows)
+
+-- 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 rows)
+
+END;
+-- Read out a portion
+BEGIN;
+UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' 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
+----------
+(0 rows)
+
+-- 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
+--------
+(0 rows)
+
+SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lowrite(fd, 'n') FROM lotest_stash_values;
+ lowrite
+---------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_lseek(fd, -156, 2) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT loread(fd, 35) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+-- Test resource management
+BEGIN;
+SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
+ lo_open
+---------
+(0 rows)
+
+ABORT;
+-- Test truncation.
+BEGIN;
+UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
+SELECT lo_truncate(fd, 10) FROM lotest_stash_values;
+ lo_truncate
+-------------
+(0 rows)
+
+SELECT loread(fd, 15) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_truncate(fd, 10000) FROM lotest_stash_values;
+ lo_truncate
+-------------
+(0 rows)
+
+SELECT loread(fd, 10) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_truncate(fd, 5000) FROM lotest_stash_values;
+ lo_truncate
+-------------
+(0 rows)
+
+SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+-- lo_unlink(lobjId oid) returns integer
+-- return value appears to always be 1
+SELECT lo_unlink(loid) from lotest_stash_values;
+ lo_unlink
+-----------
+(0 rows)
+
+TRUNCATE lotest_stash_values;
+INSERT INTO lotest_stash_values (loid) VALUES( lo_import('@abs_srcdir@/data/tenk.data') );
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+BEGIN;
+UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' 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
+----------
+(0 rows)
+
+-- 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
+--------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
+ lowrite
+---------
+(0 rows)
+
+SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT loread(fd, 36) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
+ lo_export
+-----------
+(0 rows)
+
+\lo_import '@abs_builddir@/results/lotest.txt'
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+\set newloid :LASTOID
+-- just make sure \lo_export does not barf
+\lo_export :newloid '@abs_builddir@/results/lotest2.txt'
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+-- 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
+-----------
+(0 rows)
+
+\lo_unlink :newloid
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+TRUNCATE lotest_stash_values;