At Tue, 7 Jun 2022 16:33:53 +0900, Michael Paquier <mich...@paquier.xyz> wrote in > On Tue, Jun 07, 2022 at 04:05:20PM +0900, Kyotaro Horiguchi wrote: > > If I want to read a file that I'm not sure of the existence but I want > > to read the whole file if exists, I would call > > pg_read_binary_file('path', 0, -1, true) but unfortunately this > > doesn't work. > > Yeah, the "normal" cases that I have seen in the past just used an > extra call to pg_stat_file() to retrieve the size of the file before > reading it, but arguably it does not help if the file gets extended > between the stat() call and the read() call (we don't need to care > about this case with pg_rewind that has been the reason why the > missing_ok argument was introduced first, for one, as file extensions > don't matter as we'd replay from the LSN point where the rewind > began, adding the new blocks at replay).
Sure. > There is also an argument for supporting negative values rather than > just -1. For example -2 could mean to read all the file except the > last byte. Or you could have an extra flavor, as of > pg_read_file(text, bool) to read the whole by default. Supporting > just -1 as special value for the amount of data to read would be > confusing IMO. So I would tend to choose for a set of arguments based > on (text, bool). I'm not sure about the negative length smaller than -1, since I don't find an apprpriate offset that represents (last byte + 1). 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 the attached pg_read(_binary)_file_all() is modifiedf so that they have the different body from pg_read(_binary)_file(). (function comments needs to be edited and docs are needed) regards. -- Kyotaro Horiguchi NTT Open Source Software Center
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 2bf5219256..62e16b014e 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -349,7 +349,6 @@ pg_read_binary_file(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } - /* * Wrapper functions for the 1 and 3 argument variants of pg_read_file_v2() * and pg_read_binary_file(). @@ -367,7 +366,21 @@ pg_read_file_off_len(PG_FUNCTION_ARGS) Datum pg_read_file_all(PG_FUNCTION_ARGS) { - return pg_read_file_v2(fcinfo); + text *filename_t = PG_GETARG_TEXT_PP(0); + bool missing_ok = false; + char *filename; + text *result; + + if (PG_NARGS() >= 2) + missing_ok = PG_GETARG_BOOL(1); + + filename = convert_and_check_filename(filename_t); + + result = read_text_file(filename, 0, -1, missing_ok); + if (result) + PG_RETURN_TEXT_P(result); + else + PG_RETURN_NULL(); } Datum @@ -379,7 +392,21 @@ pg_read_binary_file_off_len(PG_FUNCTION_ARGS) Datum pg_read_binary_file_all(PG_FUNCTION_ARGS) { - return pg_read_binary_file(fcinfo); + text *filename_t = PG_GETARG_TEXT_PP(0); + bool missing_ok = false; + char *filename; + bytea *result; + + if (PG_NARGS() >= 2) + missing_ok = PG_GETARG_BOOL(1); + + filename = convert_and_check_filename(filename_t); + + result = read_binary_file(filename, 0, -1, missing_ok); + if (result) + PG_RETURN_BYTEA_P(result); + else + PG_RETURN_NULL(); } /* diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 87aa571a33..e180286749 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 => '8530', descr => 'read text from a file', + proname => 'pg_read_file', provolatile => 'v', prorettype => 'text', + proargtypes => 'text bool', prosrc => 'pg_read_file_all' }, { 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 => '8529', descr => 'read bytea from a file', + proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea', + proargtypes => 'text bool', prosrc => 'pg_read_binary_file_all' }, { oid => '2625', descr => 'list all files in a directory', proname => 'pg_ls_dir', prorows => '1000', proretset => 't', provolatile => 'v', prorettype => 'text', proargtypes => 'text',