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

Commitcb2acb1

Browse files
committed
Add missing_ok option to the SQL functions for reading files.
This makes it possible to use the functions without getting errors, if thereis a chance that the file might be removed or renamed concurrently.pg_rewind needs to do just that, although this could be useful for otherpurposes too. (The changes to pg_rewind to use these functions will come ina separate commit.)The read_binary_file() function isn't very well-suited for extensions.c'spurposes anymore, if it ever was. So bite the bullet and make a copy of itin extension.c, tailored for that use case. This seems better than theaccidental code reuse, even if it's a some more lines of code.Michael Paquier, with plenty of kibitzing by me.
1 parentcca8ba9 commitcb2acb1

File tree

6 files changed

+272
-100
lines changed

6 files changed

+272
-100
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17811,43 +17811,63 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
1781117811
<tbody>
1781217812
<row>
1781317813
<entry>
17814-
<literal><function>pg_ls_dir(<parameter>dirname</> <type>text</>)</function></literal>
17814+
<literal><function>pg_ls_dir(<parameter>dirname</> <type>text</> [, <parameter>missing_ok</> <type>boolean</>, <parameter>include_dot_dirs</> <type>boolean</>])</function></literal>
1781517815
</entry>
1781617816
<entry><type>setof text</type></entry>
17817-
<entry>List the contents of a directory</entry>
17817+
<entry>
17818+
List the contents of a directory.
17819+
</entry>
1781817820
</row>
1781917821
<row>
1782017822
<entry>
17821-
<literal><function>pg_read_file(<parameter>filename</> <type>text</> [, <parameter>offset</> <type>bigint</>, <parameter>length</> <type>bigint</>])</function></literal>
17823+
<literal><function>pg_read_file(<parameter>filename</> <type>text</> [, <parameter>offset</> <type>bigint</>, <parameter>length</> <type>bigint</> [, <parameter>missing_ok</> <type>boolean</>]])</function></literal>
1782217824
</entry>
1782317825
<entry><type>text</type></entry>
17824-
<entry>Return the contents of a text file</entry>
17826+
<entry>
17827+
Return the contents of a text file.
17828+
</entry>
1782517829
</row>
1782617830
<row>
1782717831
<entry>
17828-
<literal><function>pg_read_binary_file(<parameter>filename</> <type>text</> [, <parameter>offset</> <type>bigint</>, <parameter>length</> <type>bigint</>])</function></literal>
17832+
<literal><function>pg_read_binary_file(<parameter>filename</> <type>text</> [, <parameter>offset</> <type>bigint</>, <parameter>length</> <type>bigint</> [, <parameter>missing_ok</> <type>boolean</>]])</function></literal>
1782917833
</entry>
1783017834
<entry><type>bytea</type></entry>
17831-
<entry>Return the contents of a file</entry>
17835+
<entry>
17836+
Return the contents of a file.
17837+
</entry>
1783217838
</row>
1783317839
<row>
1783417840
<entry>
17835-
<literal><function>pg_stat_file(<parameter>filename</> <type>text</>)</function></literal>
17841+
<literal><function>pg_stat_file(<parameter>filename</> <type>text</>[, <parameter>missing_ok</> <type>boolean</type>])</function></literal>
1783617842
</entry>
1783717843
<entry><type>record</type></entry>
17838-
<entry>Return information about a file</entry>
17844+
<entry>
17845+
Return information about a file.
17846+
</entry>
1783917847
</row>
1784017848
</tbody>
1784117849
</tgroup>
1784217850
</table>
1784317851

17852+
<para>
17853+
All of these functions take an optional <parameter>missing_ok</> parameter,
17854+
which specifies the behaviour when the file or directory does not exist.
17855+
If <literal>true</literal>, the function returns NULL (except
17856+
<function>pg_ls_dir</>, which returns an empty result set). If
17857+
<literal>false</>, an error is raised. The default is <literal>false</>.
17858+
</para>
17859+
1784417860
<indexterm>
1784517861
<primary>pg_ls_dir</primary>
1784617862
</indexterm>
1784717863
<para>
17848-
<function>pg_ls_dir</> returns all the names in the specified
17849-
directory, except the special entries <quote><literal>.</></> and
17850-
<quote><literal>..</></>.
17864+
<function>pg_ls_dir</> returns the names of all files (and directories
17865+
and other special files) in the specified directory. The <parameter>
17866+
include_dot_dirs</> indicates whether <quote>.</> and <quote>..</> are
17867+
included in the result set. The default is to exclude them
17868+
(<literal>false/>), but including them can be useful when
17869+
<parameter>missing_ok</> is <literal>true</literal>, to distinguish an
17870+
empty directory from an non-existent directory.
1785117871
</para>
1785217872

1785317873
<indexterm>

‎src/backend/commands/extension.c

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#include<dirent.h>
2727
#include<limits.h>
28+
#include<sys/file.h>
29+
#include<sys/stat.h>
2830
#include<unistd.h>
2931

3032
#include"access/htup_details.h"
@@ -51,6 +53,7 @@
5153
#include"utils/builtins.h"
5254
#include"utils/fmgroids.h"
5355
#include"utils/lsyscache.h"
56+
#include"utils/memutils.h"
5457
#include"utils/rel.h"
5558
#include"utils/snapmgr.h"
5659
#include"utils/tqual.h"
@@ -103,6 +106,7 @@ static void ApplyExtensionUpdates(Oid extensionOid,
103106
ExtensionControlFile*pcontrol,
104107
constchar*initialVersion,
105108
List*updateVersions);
109+
staticchar*read_whole_file(constchar*filename,int*length);
106110

107111

108112
/*
@@ -635,12 +639,11 @@ read_extension_script_file(const ExtensionControlFile *control,
635639
constchar*filename)
636640
{
637641
intsrc_encoding;
638-
bytea*content;
639642
char*src_str;
640643
char*dest_str;
641644
intlen;
642645

643-
content=read_binary_file(filename,0,-1);
646+
src_str=read_whole_file(filename,&len);
644647

645648
/* use database encoding if not given */
646649
if (control->encoding<0)
@@ -649,21 +652,15 @@ read_extension_script_file(const ExtensionControlFile *control,
649652
src_encoding=control->encoding;
650653

651654
/* make sure that source string is valid in the expected encoding */
652-
len=VARSIZE_ANY_EXHDR(content);
653-
src_str=VARDATA_ANY(content);
654655
pg_verify_mbstr_len(src_encoding,src_str,len, false);
655656

656-
/* convert the encoding to the database encoding */
657+
/*
658+
* Convert the encoding to the database encoding. read_whole_file
659+
* null-terminated the string, so if no conversion happens the string is
660+
* valid as is.
661+
*/
657662
dest_str=pg_any_to_server(src_str,len,src_encoding);
658663

659-
/* if no conversion happened, we have to arrange for null termination */
660-
if (dest_str==src_str)
661-
{
662-
dest_str= (char*)palloc(len+1);
663-
memcpy(dest_str,src_str,len);
664-
dest_str[len]='\0';
665-
}
666-
667664
returndest_str;
668665
}
669666

@@ -3008,3 +3005,49 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
30083005

30093006
returnextension;
30103007
}
3008+
3009+
/*
3010+
* Read the whole of file into memory.
3011+
*
3012+
* The file contents are returned as a single palloc'd chunk. For convenience
3013+
* of the callers, an extra \0 byte is added to the end.
3014+
*/
3015+
staticchar*
3016+
read_whole_file(constchar*filename,int*length)
3017+
{
3018+
char*buf;
3019+
FILE*file;
3020+
size_tbytes_to_read;
3021+
structstatfst;
3022+
3023+
if (stat(filename,&fst)<0)
3024+
ereport(ERROR,
3025+
(errcode_for_file_access(),
3026+
errmsg("could not stat file \"%s\": %m",filename)));
3027+
3028+
if (fst.st_size> (MaxAllocSize-1))
3029+
ereport(ERROR,
3030+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3031+
errmsg("file too large")));
3032+
bytes_to_read= (size_t)fst.st_size;
3033+
3034+
if ((file=AllocateFile(filename,PG_BINARY_R))==NULL)
3035+
ereport(ERROR,
3036+
(errcode_for_file_access(),
3037+
errmsg("could not open file \"%s\" for reading: %m",
3038+
filename)));
3039+
3040+
buf= (char*)palloc(bytes_to_read+1);
3041+
3042+
*length=fread(buf,1,bytes_to_read,file);
3043+
3044+
if (ferror(file))
3045+
ereport(ERROR,
3046+
(errcode_for_file_access(),
3047+
errmsg("could not read file \"%s\": %m",filename)));
3048+
3049+
FreeFile(file);
3050+
3051+
buf[*length]='\0';
3052+
returnbuf;
3053+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp