mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Support pg_read_[binary_]file (filename, missing_ok).
There wasn't an especially nice way to read all of a file while passing missing_ok = true. Add an additional overloaded variant to support that use-case. While here, refactor the C code to avoid a rats-nest of PG_NARGS checks, instead handling the argument collection in the outer wrapper functions. It's a bit longer this way, but far more straightforward. (Upon looking at the code coverage report for genfile.c, I was impelled to also add a test case for pg_stat_file() -- tgl) Kyotaro Horiguchi Discussion: https://postgr.es/m/20220607.160520.1984541900138970018.horikyota.ntt@gmail.com
This commit is contained in:
@ -28411,13 +28411,23 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
|
|||||||
considered.
|
considered.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When granting privilege on these functions, note that the table entries
|
||||||
|
showing optional parameters are mostly implemented as several physical
|
||||||
|
functions with different parameter lists. Privilege must be granted
|
||||||
|
separately on each such function, if it is to be
|
||||||
|
used. <application>psql</application>'s <command>\df</command> command
|
||||||
|
can be useful to check what the actual function signatures are.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Some of these functions take an optional <parameter>missing_ok</parameter>
|
Some of these functions take an optional <parameter>missing_ok</parameter>
|
||||||
parameter, which specifies the behavior when the file or directory does
|
parameter, which specifies the behavior when the file or directory does
|
||||||
not exist. If <literal>true</literal>, the function
|
not exist. If <literal>true</literal>, the function
|
||||||
returns <literal>NULL</literal> or an empty result set, as appropriate.
|
returns <literal>NULL</literal> or an empty result set, as appropriate.
|
||||||
If <literal>false</literal>, an error is raised. The default
|
If <literal>false</literal>, an error is raised. (Failure conditions
|
||||||
is <literal>false</literal>.
|
other than <quote>file not found</quote> are reported as errors in any
|
||||||
|
case.) The default is <literal>false</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<table id="functions-admin-genfile-table">
|
<table id="functions-admin-genfile-table">
|
||||||
@ -28636,7 +28646,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
|
|||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>pg_read_file</primary>
|
<primary>pg_read_file</primary>
|
||||||
</indexterm>
|
</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>
|
<returnvalue>text</returnvalue>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@ -28661,7 +28671,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
|
|||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>pg_read_binary_file</primary>
|
<primary>pg_read_binary_file</primary>
|
||||||
</indexterm>
|
</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>
|
<returnvalue>bytea</returnvalue>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
|
@ -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) 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) FROM public;
|
||||||
|
|
||||||
REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint,boolean) 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) 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) FROM public;
|
||||||
|
|
||||||
REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public;
|
REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public;
|
||||||
|
@ -278,81 +278,50 @@ pg_read_file(PG_FUNCTION_ARGS)
|
|||||||
*
|
*
|
||||||
* No superuser check done here- instead privileges are handled by the
|
* No superuser check done here- instead privileges are handled by the
|
||||||
* GRANT system.
|
* GRANT system.
|
||||||
|
*
|
||||||
|
* If read_to_eof is true, bytes_to_read must be -1, otherwise negative values
|
||||||
|
* are not allowed for bytes_to_read.
|
||||||
*/
|
*/
|
||||||
Datum
|
static text *
|
||||||
pg_read_file_v2(PG_FUNCTION_ARGS)
|
pg_read_file_common(text *filename_t, int64 seek_offset, int64 bytes_to_read,
|
||||||
|
bool read_to_eof, bool missing_ok)
|
||||||
{
|
{
|
||||||
text *filename_t = PG_GETARG_TEXT_PP(0);
|
if (read_to_eof)
|
||||||
int64 seek_offset = 0;
|
Assert(bytes_to_read == -1);
|
||||||
int64 bytes_to_read = -1;
|
else if (bytes_to_read < 0)
|
||||||
bool missing_ok = false;
|
ereport(ERROR,
|
||||||
char *filename;
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
text *result;
|
errmsg("requested length cannot be negative")));
|
||||||
|
|
||||||
/* handle optional arguments */
|
return read_text_file(convert_and_check_filename(filename_t),
|
||||||
if (PG_NARGS() >= 3)
|
seek_offset, bytes_to_read, missing_ok);
|
||||||
{
|
|
||||||
seek_offset = PG_GETARG_INT64(1);
|
|
||||||
bytes_to_read = PG_GETARG_INT64(2);
|
|
||||||
|
|
||||||
if (bytes_to_read < 0)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
||||||
errmsg("requested length cannot be negative")));
|
|
||||||
}
|
|
||||||
if (PG_NARGS() >= 4)
|
|
||||||
missing_ok = PG_GETARG_BOOL(3);
|
|
||||||
|
|
||||||
filename = convert_and_check_filename(filename_t);
|
|
||||||
|
|
||||||
result = read_text_file(filename, seek_offset, bytes_to_read, missing_ok);
|
|
||||||
if (result)
|
|
||||||
PG_RETURN_TEXT_P(result);
|
|
||||||
else
|
|
||||||
PG_RETURN_NULL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a section of a file, returning it as bytea
|
* Read a section of a file, returning it as bytea
|
||||||
|
*
|
||||||
|
* Parameters are interpreted the same as pg_read_file_common().
|
||||||
*/
|
*/
|
||||||
Datum
|
static bytea *
|
||||||
pg_read_binary_file(PG_FUNCTION_ARGS)
|
pg_read_binary_file_common(text *filename_t,
|
||||||
|
int64 seek_offset, int64 bytes_to_read,
|
||||||
|
bool read_to_eof, bool missing_ok)
|
||||||
{
|
{
|
||||||
text *filename_t = PG_GETARG_TEXT_PP(0);
|
if (read_to_eof)
|
||||||
int64 seek_offset = 0;
|
Assert(bytes_to_read == -1);
|
||||||
int64 bytes_to_read = -1;
|
else if (bytes_to_read < 0)
|
||||||
bool missing_ok = false;
|
ereport(ERROR,
|
||||||
char *filename;
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
bytea *result;
|
errmsg("requested length cannot be negative")));
|
||||||
|
|
||||||
/* handle optional arguments */
|
return read_binary_file(convert_and_check_filename(filename_t),
|
||||||
if (PG_NARGS() >= 3)
|
seek_offset, bytes_to_read, missing_ok);
|
||||||
{
|
|
||||||
seek_offset = PG_GETARG_INT64(1);
|
|
||||||
bytes_to_read = PG_GETARG_INT64(2);
|
|
||||||
|
|
||||||
if (bytes_to_read < 0)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
||||||
errmsg("requested length cannot be negative")));
|
|
||||||
}
|
|
||||||
if (PG_NARGS() >= 4)
|
|
||||||
missing_ok = PG_GETARG_BOOL(3);
|
|
||||||
|
|
||||||
filename = convert_and_check_filename(filename_t);
|
|
||||||
|
|
||||||
result = read_binary_file(filename, seek_offset,
|
|
||||||
bytes_to_read, missing_ok);
|
|
||||||
if (result)
|
|
||||||
PG_RETURN_BYTEA_P(result);
|
|
||||||
else
|
|
||||||
PG_RETURN_NULL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper functions for the 1 and 3 argument variants of pg_read_file_v2()
|
* Wrapper functions for the variants of SQL functions pg_read_file() and
|
||||||
* and pg_read_binary_file().
|
* pg_read_binary_file().
|
||||||
*
|
*
|
||||||
* These are necessary to pass the sanity check in opr_sanity, which checks
|
* These are necessary to pass the sanity check in opr_sanity, which checks
|
||||||
* that all built-in functions that share the implementing C function take
|
* that all built-in functions that share the implementing C function take
|
||||||
@ -361,25 +330,126 @@ pg_read_binary_file(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
pg_read_file_off_len(PG_FUNCTION_ARGS)
|
pg_read_file_off_len(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
return pg_read_file_v2(fcinfo);
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
int64 seek_offset = PG_GETARG_INT64(1);
|
||||||
|
int64 bytes_to_read = PG_GETARG_INT64(2);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_file_common(filename_t, seek_offset, bytes_to_read,
|
||||||
|
false, false);
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_read_file_off_len_missing(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
int64 seek_offset = PG_GETARG_INT64(1);
|
||||||
|
int64 bytes_to_read = PG_GETARG_INT64(2);
|
||||||
|
bool missing_ok = PG_GETARG_BOOL(3);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_file_common(filename_t, seek_offset, bytes_to_read,
|
||||||
|
false, missing_ok);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
pg_read_file_all(PG_FUNCTION_ARGS)
|
pg_read_file_all(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
return pg_read_file_v2(fcinfo);
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_file_common(filename_t, 0, -1, true, false);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_read_file_all_missing(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
bool missing_ok = PG_GETARG_BOOL(1);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_file_common(filename_t, 0, -1, true, missing_ok);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
pg_read_binary_file_off_len(PG_FUNCTION_ARGS)
|
pg_read_binary_file_off_len(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
return pg_read_binary_file(fcinfo);
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
int64 seek_offset = PG_GETARG_INT64(1);
|
||||||
|
int64 bytes_to_read = PG_GETARG_INT64(2);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_binary_file_common(filename_t, seek_offset, bytes_to_read,
|
||||||
|
false, false);
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_read_binary_file_off_len_missing(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
int64 seek_offset = PG_GETARG_INT64(1);
|
||||||
|
int64 bytes_to_read = PG_GETARG_INT64(2);
|
||||||
|
bool missing_ok = PG_GETARG_BOOL(3);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_binary_file_common(filename_t, seek_offset, bytes_to_read,
|
||||||
|
false, missing_ok);
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
pg_read_binary_file_all(PG_FUNCTION_ARGS)
|
pg_read_binary_file_all(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
return pg_read_binary_file(fcinfo);
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_binary_file_common(filename_t, 0, -1, true, false);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_read_binary_file_all_missing(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *filename_t = PG_GETARG_TEXT_PP(0);
|
||||||
|
bool missing_ok = PG_GETARG_BOOL(1);
|
||||||
|
text *ret;
|
||||||
|
|
||||||
|
ret = pg_read_binary_file_common(filename_t, 0, -1, true, missing_ok);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202207271
|
#define CATALOG_VERSION_NO 202207291
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6415,7 +6415,8 @@
|
|||||||
proargtypes => 'text int8 int8', prosrc => 'pg_read_file_off_len' },
|
proargtypes => 'text int8 int8', prosrc => 'pg_read_file_off_len' },
|
||||||
{ oid => '3293', descr => 'read text from a file',
|
{ oid => '3293', descr => 'read text from a file',
|
||||||
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
|
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
|
||||||
proargtypes => 'text int8 int8 bool', prosrc => 'pg_read_file_v2' },
|
proargtypes => 'text int8 int8 bool',
|
||||||
|
prosrc => 'pg_read_file_off_len_missing' },
|
||||||
{ oid => '4100',
|
{ oid => '4100',
|
||||||
descr => 'read text from a file - old version for adminpack 1.0',
|
descr => 'read text from a file - old version for adminpack 1.0',
|
||||||
proname => 'pg_read_file_old', provolatile => 'v', prorettype => 'text',
|
proname => 'pg_read_file_old', provolatile => 'v', prorettype => 'text',
|
||||||
@ -6423,15 +6424,22 @@
|
|||||||
{ oid => '3826', descr => 'read text from a file',
|
{ oid => '3826', descr => 'read text from a file',
|
||||||
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
|
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
|
||||||
proargtypes => 'text', prosrc => 'pg_read_file_all' },
|
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',
|
{ oid => '3827', descr => 'read bytea from a file',
|
||||||
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
|
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
|
||||||
proargtypes => 'text int8 int8', prosrc => 'pg_read_binary_file_off_len' },
|
proargtypes => 'text int8 int8', prosrc => 'pg_read_binary_file_off_len' },
|
||||||
{ oid => '3295', descr => 'read bytea from a file',
|
{ oid => '3295', descr => 'read bytea from a file',
|
||||||
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
|
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
|
||||||
proargtypes => 'text int8 int8 bool', prosrc => 'pg_read_binary_file' },
|
proargtypes => 'text int8 int8 bool',
|
||||||
|
prosrc => 'pg_read_binary_file_off_len_missing' },
|
||||||
{ oid => '3828', descr => 'read bytea from a file',
|
{ oid => '3828', descr => 'read bytea from a file',
|
||||||
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
|
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
|
||||||
proargtypes => 'text', prosrc => 'pg_read_binary_file_all' },
|
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',
|
{ oid => '2625', descr => 'list all files in a directory',
|
||||||
proname => 'pg_ls_dir', prorows => '1000', proretset => 't',
|
proname => 'pg_ls_dir', prorows => '1000', proretset => 't',
|
||||||
provolatile => 'v', prorettype => 'text', proargtypes => 'text',
|
provolatile => 'v', prorettype => 'text', proargtypes => 'text',
|
||||||
|
@ -372,6 +372,68 @@ select count(*) >= 0 as ok from pg_ls_archive_statusdir();
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- pg_read_file()
|
||||||
|
select length(pg_read_file('postgresql.auto.conf')) > 30;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select length(pg_read_file('postgresql.auto.conf', 1, 30));
|
||||||
|
length
|
||||||
|
--------
|
||||||
|
30
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test missing_ok
|
||||||
|
select pg_read_file('does not exist'); -- error
|
||||||
|
ERROR: could not open file "does not exist" for reading: No such file or directory
|
||||||
|
select pg_read_file('does not exist', true) IS NULL; -- ok
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test invalid argument
|
||||||
|
select pg_read_file('does not exist', 0, -1); -- error
|
||||||
|
ERROR: requested length cannot be negative
|
||||||
|
select pg_read_file('does not exist', 0, -1, true); -- error
|
||||||
|
ERROR: requested length cannot be negative
|
||||||
|
-- pg_read_binary_file()
|
||||||
|
select length(pg_read_binary_file('postgresql.auto.conf')) > 30;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select length(pg_read_binary_file('postgresql.auto.conf', 1, 30));
|
||||||
|
length
|
||||||
|
--------
|
||||||
|
30
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test missing_ok
|
||||||
|
select pg_read_binary_file('does not exist'); -- error
|
||||||
|
ERROR: could not open file "does not exist" for reading: No such file or directory
|
||||||
|
select pg_read_binary_file('does not exist', true) IS NULL; -- ok
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test invalid argument
|
||||||
|
select pg_read_binary_file('does not exist', 0, -1); -- error
|
||||||
|
ERROR: requested length cannot be negative
|
||||||
|
select pg_read_binary_file('does not exist', 0, -1, true); -- error
|
||||||
|
ERROR: requested length cannot be negative
|
||||||
|
-- pg_stat_file()
|
||||||
|
select size > 30, isdir from pg_stat_file('postgresql.auto.conf');
|
||||||
|
?column? | isdir
|
||||||
|
----------+-------
|
||||||
|
t | f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- pg_ls_dir()
|
||||||
select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1;
|
select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1;
|
||||||
a
|
a
|
||||||
------
|
------
|
||||||
@ -401,12 +463,14 @@ select count(*) = 1 as dot_found
|
|||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- pg_timezone_names()
|
||||||
select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1;
|
select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1;
|
||||||
name
|
name
|
||||||
------
|
------
|
||||||
UTC
|
UTC
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- pg_tablespace_databases()
|
||||||
select count(*) > 0 from
|
select count(*) > 0 from
|
||||||
(select pg_tablespace_databases(oid) as pts from pg_tablespace
|
(select pg_tablespace_databases(oid) as pts from pg_tablespace
|
||||||
where spcname = 'pg_default') pts
|
where spcname = 'pg_default') pts
|
||||||
|
@ -123,6 +123,30 @@ from (select pg_ls_waldir() w) ss where length((w).name) = 24 limit 1;
|
|||||||
|
|
||||||
select count(*) >= 0 as ok from pg_ls_archive_statusdir();
|
select count(*) >= 0 as ok from pg_ls_archive_statusdir();
|
||||||
|
|
||||||
|
-- pg_read_file()
|
||||||
|
select length(pg_read_file('postgresql.auto.conf')) > 30;
|
||||||
|
select length(pg_read_file('postgresql.auto.conf', 1, 30));
|
||||||
|
-- Test missing_ok
|
||||||
|
select pg_read_file('does not exist'); -- error
|
||||||
|
select pg_read_file('does not exist', true) IS NULL; -- ok
|
||||||
|
-- Test invalid argument
|
||||||
|
select pg_read_file('does not exist', 0, -1); -- error
|
||||||
|
select pg_read_file('does not exist', 0, -1, true); -- error
|
||||||
|
|
||||||
|
-- pg_read_binary_file()
|
||||||
|
select length(pg_read_binary_file('postgresql.auto.conf')) > 30;
|
||||||
|
select length(pg_read_binary_file('postgresql.auto.conf', 1, 30));
|
||||||
|
-- Test missing_ok
|
||||||
|
select pg_read_binary_file('does not exist'); -- error
|
||||||
|
select pg_read_binary_file('does not exist', true) IS NULL; -- ok
|
||||||
|
-- Test invalid argument
|
||||||
|
select pg_read_binary_file('does not exist', 0, -1); -- error
|
||||||
|
select pg_read_binary_file('does not exist', 0, -1, true); -- error
|
||||||
|
|
||||||
|
-- pg_stat_file()
|
||||||
|
select size > 30, isdir from pg_stat_file('postgresql.auto.conf');
|
||||||
|
|
||||||
|
-- pg_ls_dir()
|
||||||
select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1;
|
select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1;
|
||||||
-- Test missing_ok (second argument)
|
-- Test missing_ok (second argument)
|
||||||
select pg_ls_dir('does not exist', false, false); -- error
|
select pg_ls_dir('does not exist', false, false); -- error
|
||||||
@ -133,8 +157,10 @@ select count(*) = 1 as dot_found
|
|||||||
select count(*) = 1 as dot_found
|
select count(*) = 1 as dot_found
|
||||||
from pg_ls_dir('.', false, false) as ls where ls = '.';
|
from pg_ls_dir('.', false, false) as ls where ls = '.';
|
||||||
|
|
||||||
|
-- pg_timezone_names()
|
||||||
select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1;
|
select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1;
|
||||||
|
|
||||||
|
-- pg_tablespace_databases()
|
||||||
select count(*) > 0 from
|
select count(*) > 0 from
|
||||||
(select pg_tablespace_databases(oid) as pts from pg_tablespace
|
(select pg_tablespace_databases(oid) as pts from pg_tablespace
|
||||||
where spcname = 'pg_default') pts
|
where spcname = 'pg_default') pts
|
||||||
|
Reference in New Issue
Block a user