At Tue, 07 Jun 2022 17:29:31 +0900 (JST), Kyotaro Horiguchi <horikyota....@gmail.com> wrote in > pg_read_file(text, bool) makes sense to me, but it doesn't seem like > to be able to share C function with other variations. > pg_read_binary_file() need to accept some out-of-range value for > offset or length to signal that offset and length are not specified.
In this version all the polypmorphic variations share the same body function. I tempted to add tail-reading feature but it would be another feature. > (function comments needs to be edited and docs are needed) - Simplified the implementation (by complexifying argument handling..). - REVOKEd EXECUTE from the new functions. - Edited the signature of the two functions. > - pg_read_file ( filename text [, offset bigint, length bigint [, missing_ok > boolean ]] ) → text > + pg_read_file ( filename text [, offset bigint, length bigint ] [, > missing_ok boolean ] ) → text And registered this to the next CF. regards. -- Kyotaro Horiguchi NTT Open Source Software Center
>From 5d344fb56cded75e22cb4e56bcf1c10a31f5d4bb Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi <horikyota....@gmail.com> Date: Thu, 30 Jun 2022 10:30:35 +0900 Subject: [PATCH v3] Add an argument variation to pg_read_file Let the functions pg_read_file and pg_read_binary_file have the argument variation of f(filename, missing_ok) so that the functions can read the whole file tolerating the file to be missing. --- doc/src/sgml/func.sgml | 4 +-- src/backend/catalog/system_functions.sql | 4 +++ src/backend/utils/adt/genfile.c | 33 +++++++++++++++++++----- src/include/catalog/pg_proc.dat | 6 +++++ 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 7b652460a1..34d76b74e4 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -28593,7 +28593,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size <indexterm> <primary>pg_read_file</primary> </indexterm> - <function>pg_read_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>bigint</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional></optional> ) + <function>pg_read_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>bigint</type> </optional> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional> ) <returnvalue>text</returnvalue> </para> <para> @@ -28618,7 +28618,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size <indexterm> <primary>pg_read_binary_file</primary> </indexterm> - <function>pg_read_binary_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>bigint</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional></optional> ) + <function>pg_read_binary_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>bigint</type> </optional> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional> ) <returnvalue>bytea</returnvalue> </para> <para> diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 73da687d5d..30a048f6b0 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -659,12 +659,16 @@ REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public; REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_read_file(text,boolean) FROM public; + REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint) FROM public; REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint,boolean) FROM public; REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,boolean) FROM public; + REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint) FROM public; REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public; diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 2bf5219256..1a09431a79 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -278,6 +278,9 @@ pg_read_file(PG_FUNCTION_ARGS) * * No superuser check done here- instead privileges are handled by the * GRANT system. + * + * The two-argument variation of this function supposes the second argument as + * to be a Boolean. */ Datum pg_read_file_v2(PG_FUNCTION_ARGS) @@ -290,7 +293,9 @@ pg_read_file_v2(PG_FUNCTION_ARGS) text *result; /* handle optional arguments */ - if (PG_NARGS() >= 3) + if (PG_NARGS() == 2) + missing_ok = PG_GETARG_BOOL(1); + else if (PG_NARGS() >= 3) { seek_offset = PG_GETARG_INT64(1); bytes_to_read = PG_GETARG_INT64(2); @@ -299,9 +304,10 @@ pg_read_file_v2(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length cannot be negative"))); + + if (PG_NARGS() >= 4) + missing_ok = PG_GETARG_BOOL(3); } - if (PG_NARGS() >= 4) - missing_ok = PG_GETARG_BOOL(3); filename = convert_and_check_filename(filename_t); @@ -326,6 +332,8 @@ pg_read_binary_file(PG_FUNCTION_ARGS) bytea *result; /* handle optional arguments */ + if (PG_NARGS() == 2) + missing_ok = PG_GETARG_BOOL(1); if (PG_NARGS() >= 3) { seek_offset = PG_GETARG_INT64(1); @@ -335,9 +343,10 @@ pg_read_binary_file(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length cannot be negative"))); + + if (PG_NARGS() >= 4) + missing_ok = PG_GETARG_BOOL(3); } - if (PG_NARGS() >= 4) - missing_ok = PG_GETARG_BOOL(3); filename = convert_and_check_filename(filename_t); @@ -351,7 +360,7 @@ pg_read_binary_file(PG_FUNCTION_ARGS) /* - * Wrapper functions for the 1 and 3 argument variants of pg_read_file_v2() + * Wrapper functions for the 1 to 3 argument variants of pg_read_file_v2() * and pg_read_binary_file(). * * These are necessary to pass the sanity check in opr_sanity, which checks @@ -364,6 +373,12 @@ pg_read_file_off_len(PG_FUNCTION_ARGS) return pg_read_file_v2(fcinfo); } +Datum +pg_read_file_all_missing(PG_FUNCTION_ARGS) +{ + return pg_read_file_v2(fcinfo); +} + Datum pg_read_file_all(PG_FUNCTION_ARGS) { @@ -376,6 +391,12 @@ pg_read_binary_file_off_len(PG_FUNCTION_ARGS) return pg_read_binary_file(fcinfo); } +Datum +pg_read_binary_file_all_missing(PG_FUNCTION_ARGS) +{ + return pg_read_binary_file(fcinfo); +} + Datum pg_read_binary_file_all(PG_FUNCTION_ARGS) { diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 87aa571a33..84be83610a 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6423,6 +6423,9 @@ { oid => '3826', descr => 'read text from a file', proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', proargtypes => 'text', prosrc => 'pg_read_file_all' }, +{ oid => '8025', descr => 'read text from a file', + proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', + proargtypes => 'text bool', prosrc => 'pg_read_file_all_missing' }, { oid => '3827', descr => 'read bytea from a file', proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea', proargtypes => 'text int8 int8', prosrc => 'pg_read_binary_file_off_len' }, @@ -6432,6 +6435,9 @@ { oid => '3828', descr => 'read bytea from a file', proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea', proargtypes => 'text', prosrc => 'pg_read_binary_file_all' }, +{ oid => '8026', descr => 'read bytea from a file', + proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea', + proargtypes => 'text bool', prosrc => 'pg_read_binary_file_all_missing' }, { oid => '2625', descr => 'list all files in a directory', proname => 'pg_ls_dir', prorows => '1000', proretset => 't', provolatile => 'v', prorettype => 'text', proargtypes => 'text', -- 2.31.1