diff options
| author | Michael P | 2011-12-20 07:58:43 +0000 |
|---|---|---|
| committer | Michael P | 2011-12-20 07:58:43 +0000 |
| commit | 295aa93245d68ff0d7038ec6de931ee777ae03a6 (patch) | |
| tree | 43c0bdb630b9d6c7921dfc4fa4c66dd29f5f4bd1 /src | |
| parent | 25db704c09aedb8cf2015d88739cc213fcec2635 (diff) | |
Block the usage of large objects
Regressions are modified in consequence.
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/libpq/be-fsstubs.c | 105 | ||||
| -rw-r--r-- | src/test/regress/output/largeobject_3.source | 264 |
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; |
