Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit283129e

Browse files
committed
Support pg_read_[binary_]file (filename, missing_ok).
There wasn't an especially nice way to read all of a file whilepassing missing_ok = true. Add an additional overloaded variantto support that use-case.While here, refactor the C code to avoid a rats-nest of PG_NARGSchecks, instead handling the argument collection in the outerwrapper functions. It's a bit longer this way, but far morestraightforward.(Upon looking at the code coverage report for genfile.c, I wasimpelled to also add a test case for pg_stat_file() -- tgl)Kyotaro HoriguchiDiscussion:https://postgr.es/m/20220607.160520.1984541900138970018.horikyota.ntt@gmail.com
1 parentfd96d14 commit283129e

File tree

7 files changed

+254
-72
lines changed

7 files changed

+254
-72
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28411,13 +28411,23 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
2841128411
considered.
2841228412
</para>
2841328413

28414+
<para>
28415+
When granting privilege on these functions, note that the table entries
28416+
showing optional parameters are mostly implemented as several physical
28417+
functions with different parameter lists. Privilege must be granted
28418+
separately on each such function, if it is to be
28419+
used. <application>psql</application>'s <command>\df</command> command
28420+
can be useful to check what the actual function signatures are.
28421+
</para>
28422+
2841428423
<para>
2841528424
Some of these functions take an optional <parameter>missing_ok</parameter>
2841628425
parameter, which specifies the behavior when the file or directory does
2841728426
not exist. If <literal>true</literal>, the function
2841828427
returns <literal>NULL</literal> or an empty result set, as appropriate.
28419-
If <literal>false</literal>, an error is raised. The default
28420-
is <literal>false</literal>.
28428+
If <literal>false</literal>, an error is raised. (Failure conditions
28429+
other than <quote>file not found</quote> are reported as errors in any
28430+
case.) The default is <literal>false</literal>.
2842128431
</para>
2842228432

2842328433
<table id="functions-admin-genfile-table">
@@ -28636,7 +28646,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
2863628646
<indexterm>
2863728647
<primary>pg_read_file</primary>
2863828648
</indexterm>
28639-
<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> )
28649+
<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> )
2864028650
<returnvalue>text</returnvalue>
2864128651
</para>
2864228652
<para>
@@ -28661,7 +28671,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
2866128671
<indexterm>
2866228672
<primary>pg_read_binary_file</primary>
2866328673
</indexterm>
28664-
<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> )
28674+
<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> )
2866528675
<returnvalue>bytea</returnvalue>
2866628676
</para>
2866728677
<para>

‎src/backend/catalog/system_functions.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,12 +659,16 @@ REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public;
659659

660660
REVOKE EXECUTEON FUNCTION pg_read_file(text)FROM public;
661661

662+
REVOKE EXECUTEON FUNCTION pg_read_file(text,boolean)FROM public;
663+
662664
REVOKE EXECUTEON FUNCTION pg_read_file(text,bigint,bigint)FROM public;
663665

664666
REVOKE EXECUTEON FUNCTION pg_read_file(text,bigint,bigint,boolean)FROM public;
665667

666668
REVOKE EXECUTEON FUNCTION pg_read_binary_file(text)FROM public;
667669

670+
REVOKE EXECUTEON FUNCTION pg_read_binary_file(text,boolean)FROM public;
671+
668672
REVOKE EXECUTEON FUNCTION pg_read_binary_file(text,bigint,bigint)FROM public;
669673

670674
REVOKE EXECUTEON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean)FROM public;

‎src/backend/utils/adt/genfile.c

Lines changed: 135 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -278,81 +278,50 @@ pg_read_file(PG_FUNCTION_ARGS)
278278
*
279279
* No superuser check done here- instead privileges are handled by the
280280
* GRANT system.
281+
*
282+
* If read_to_eof is true, bytes_to_read must be -1, otherwise negative values
283+
* are not allowed for bytes_to_read.
281284
*/
282-
Datum
283-
pg_read_file_v2(PG_FUNCTION_ARGS)
285+
statictext*
286+
pg_read_file_common(text*filename_t,int64seek_offset,int64bytes_to_read,
287+
boolread_to_eof,boolmissing_ok)
284288
{
285-
text*filename_t=PG_GETARG_TEXT_PP(0);
286-
int64seek_offset=0;
287-
int64bytes_to_read=-1;
288-
boolmissing_ok= false;
289-
char*filename;
290-
text*result;
291-
292-
/* handle optional arguments */
293-
if (PG_NARGS() >=3)
294-
{
295-
seek_offset=PG_GETARG_INT64(1);
296-
bytes_to_read=PG_GETARG_INT64(2);
297-
298-
if (bytes_to_read<0)
299-
ereport(ERROR,
300-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
301-
errmsg("requested length cannot be negative")));
302-
}
303-
if (PG_NARGS() >=4)
304-
missing_ok=PG_GETARG_BOOL(3);
305-
306-
filename=convert_and_check_filename(filename_t);
289+
if (read_to_eof)
290+
Assert(bytes_to_read==-1);
291+
elseif (bytes_to_read<0)
292+
ereport(ERROR,
293+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
294+
errmsg("requested length cannot be negative")));
307295

308-
result=read_text_file(filename,seek_offset,bytes_to_read,missing_ok);
309-
if (result)
310-
PG_RETURN_TEXT_P(result);
311-
else
312-
PG_RETURN_NULL();
296+
returnread_text_file(convert_and_check_filename(filename_t),
297+
seek_offset,bytes_to_read,missing_ok);
313298
}
314299

315300
/*
316301
* Read a section of a file, returning it as bytea
302+
*
303+
* Parameters are interpreted the same as pg_read_file_common().
317304
*/
318-
Datum
319-
pg_read_binary_file(PG_FUNCTION_ARGS)
305+
staticbytea*
306+
pg_read_binary_file_common(text*filename_t,
307+
int64seek_offset,int64bytes_to_read,
308+
boolread_to_eof,boolmissing_ok)
320309
{
321-
text*filename_t=PG_GETARG_TEXT_PP(0);
322-
int64seek_offset=0;
323-
int64bytes_to_read=-1;
324-
boolmissing_ok= false;
325-
char*filename;
326-
bytea*result;
327-
328-
/* handle optional arguments */
329-
if (PG_NARGS() >=3)
330-
{
331-
seek_offset=PG_GETARG_INT64(1);
332-
bytes_to_read=PG_GETARG_INT64(2);
333-
334-
if (bytes_to_read<0)
335-
ereport(ERROR,
336-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
337-
errmsg("requested length cannot be negative")));
338-
}
339-
if (PG_NARGS() >=4)
340-
missing_ok=PG_GETARG_BOOL(3);
341-
342-
filename=convert_and_check_filename(filename_t);
310+
if (read_to_eof)
311+
Assert(bytes_to_read==-1);
312+
elseif (bytes_to_read<0)
313+
ereport(ERROR,
314+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
315+
errmsg("requested length cannot be negative")));
343316

344-
result=read_binary_file(filename,seek_offset,
345-
bytes_to_read,missing_ok);
346-
if (result)
347-
PG_RETURN_BYTEA_P(result);
348-
else
349-
PG_RETURN_NULL();
317+
returnread_binary_file(convert_and_check_filename(filename_t),
318+
seek_offset,bytes_to_read,missing_ok);
350319
}
351320

352321

353322
/*
354-
* Wrapper functions for the1 and 3 argumentvariants ofpg_read_file_v2()
355-
*andpg_read_binary_file().
323+
* Wrapper functions for the variants ofSQL functions pg_read_file() and
324+
* pg_read_binary_file().
356325
*
357326
* These are necessary to pass the sanity check in opr_sanity, which checks
358327
* that all built-in functions that share the implementing C function take
@@ -361,25 +330,126 @@ pg_read_binary_file(PG_FUNCTION_ARGS)
361330
Datum
362331
pg_read_file_off_len(PG_FUNCTION_ARGS)
363332
{
364-
returnpg_read_file_v2(fcinfo);
333+
text*filename_t=PG_GETARG_TEXT_PP(0);
334+
int64seek_offset=PG_GETARG_INT64(1);
335+
int64bytes_to_read=PG_GETARG_INT64(2);
336+
text*ret;
337+
338+
ret=pg_read_file_common(filename_t,seek_offset,bytes_to_read,
339+
false, false);
340+
if (!ret)
341+
PG_RETURN_NULL();
342+
343+
PG_RETURN_TEXT_P(ret);
344+
}
345+
346+
Datum
347+
pg_read_file_off_len_missing(PG_FUNCTION_ARGS)
348+
{
349+
text*filename_t=PG_GETARG_TEXT_PP(0);
350+
int64seek_offset=PG_GETARG_INT64(1);
351+
int64bytes_to_read=PG_GETARG_INT64(2);
352+
boolmissing_ok=PG_GETARG_BOOL(3);
353+
text*ret;
354+
355+
ret=pg_read_file_common(filename_t,seek_offset,bytes_to_read,
356+
false,missing_ok);
357+
358+
if (!ret)
359+
PG_RETURN_NULL();
360+
361+
PG_RETURN_TEXT_P(ret);
365362
}
366363

367364
Datum
368365
pg_read_file_all(PG_FUNCTION_ARGS)
369366
{
370-
returnpg_read_file_v2(fcinfo);
367+
text*filename_t=PG_GETARG_TEXT_PP(0);
368+
text*ret;
369+
370+
ret=pg_read_file_common(filename_t,0,-1, true, false);
371+
372+
if (!ret)
373+
PG_RETURN_NULL();
374+
375+
PG_RETURN_TEXT_P(ret);
376+
}
377+
378+
Datum
379+
pg_read_file_all_missing(PG_FUNCTION_ARGS)
380+
{
381+
text*filename_t=PG_GETARG_TEXT_PP(0);
382+
boolmissing_ok=PG_GETARG_BOOL(1);
383+
text*ret;
384+
385+
ret=pg_read_file_common(filename_t,0,-1, true,missing_ok);
386+
387+
if (!ret)
388+
PG_RETURN_NULL();
389+
390+
PG_RETURN_TEXT_P(ret);
371391
}
372392

373393
Datum
374394
pg_read_binary_file_off_len(PG_FUNCTION_ARGS)
375395
{
376-
returnpg_read_binary_file(fcinfo);
396+
text*filename_t=PG_GETARG_TEXT_PP(0);
397+
int64seek_offset=PG_GETARG_INT64(1);
398+
int64bytes_to_read=PG_GETARG_INT64(2);
399+
text*ret;
400+
401+
ret=pg_read_binary_file_common(filename_t,seek_offset,bytes_to_read,
402+
false, false);
403+
if (!ret)
404+
PG_RETURN_NULL();
405+
406+
PG_RETURN_BYTEA_P(ret);
407+
}
408+
409+
Datum
410+
pg_read_binary_file_off_len_missing(PG_FUNCTION_ARGS)
411+
{
412+
text*filename_t=PG_GETARG_TEXT_PP(0);
413+
int64seek_offset=PG_GETARG_INT64(1);
414+
int64bytes_to_read=PG_GETARG_INT64(2);
415+
boolmissing_ok=PG_GETARG_BOOL(3);
416+
text*ret;
417+
418+
ret=pg_read_binary_file_common(filename_t,seek_offset,bytes_to_read,
419+
false,missing_ok);
420+
if (!ret)
421+
PG_RETURN_NULL();
422+
423+
PG_RETURN_BYTEA_P(ret);
377424
}
378425

379426
Datum
380427
pg_read_binary_file_all(PG_FUNCTION_ARGS)
381428
{
382-
returnpg_read_binary_file(fcinfo);
429+
text*filename_t=PG_GETARG_TEXT_PP(0);
430+
text*ret;
431+
432+
ret=pg_read_binary_file_common(filename_t,0,-1, true, false);
433+
434+
if (!ret)
435+
PG_RETURN_NULL();
436+
437+
PG_RETURN_BYTEA_P(ret);
438+
}
439+
440+
Datum
441+
pg_read_binary_file_all_missing(PG_FUNCTION_ARGS)
442+
{
443+
text*filename_t=PG_GETARG_TEXT_PP(0);
444+
boolmissing_ok=PG_GETARG_BOOL(1);
445+
text*ret;
446+
447+
ret=pg_read_binary_file_common(filename_t,0,-1, true,missing_ok);
448+
449+
if (!ret)
450+
PG_RETURN_NULL();
451+
452+
PG_RETURN_BYTEA_P(ret);
383453
}
384454

385455
/*

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/*yyyymmddN */
60-
#defineCATALOG_VERSION_NO202207271
60+
#defineCATALOG_VERSION_NO202207291
6161

6262
#endif

‎src/include/catalog/pg_proc.dat

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6415,23 +6415,31 @@
64156415
proargtypes => 'text int8 int8', prosrc => 'pg_read_file_off_len' },
64166416
{ oid => '3293', descr => 'read text from a file',
64176417
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
6418-
proargtypes => 'text int8 int8 bool', prosrc => 'pg_read_file_v2' },
6418+
proargtypes => 'text int8 int8 bool',
6419+
prosrc => 'pg_read_file_off_len_missing' },
64196420
{ oid => '4100',
64206421
descr => 'read text from a file - old version for adminpack 1.0',
64216422
proname => 'pg_read_file_old', provolatile => 'v', prorettype => 'text',
64226423
proargtypes => 'text int8 int8', prosrc => 'pg_read_file' },
64236424
{ oid => '3826', descr => 'read text from a file',
64246425
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
64256426
proargtypes => 'text', prosrc => 'pg_read_file_all' },
6427+
{ oid => '8025', descr => 'read text from a file',
6428+
proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
6429+
proargtypes => 'text bool', prosrc => 'pg_read_file_all_missing' },
64266430
{ oid => '3827', descr => 'read bytea from a file',
64276431
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
64286432
proargtypes => 'text int8 int8', prosrc => 'pg_read_binary_file_off_len' },
64296433
{ oid => '3295', descr => 'read bytea from a file',
64306434
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
6431-
proargtypes => 'text int8 int8 bool', prosrc => 'pg_read_binary_file' },
6435+
proargtypes => 'text int8 int8 bool',
6436+
prosrc => 'pg_read_binary_file_off_len_missing' },
64326437
{ oid => '3828', descr => 'read bytea from a file',
64336438
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
64346439
proargtypes => 'text', prosrc => 'pg_read_binary_file_all' },
6440+
{ oid => '8026', descr => 'read bytea from a file',
6441+
proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
6442+
proargtypes => 'text bool', prosrc => 'pg_read_binary_file_all_missing' },
64356443
{ oid => '2625', descr => 'list all files in a directory',
64366444
proname => 'pg_ls_dir', prorows => '1000', proretset => 't',
64376445
provolatile => 'v', prorettype => 'text', proargtypes => 'text',

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp