From 355eddbb6dcadc994b8ce65744e7aab1b96281e6 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Mon, 9 Mar 2020 01:00:42 -0500 Subject: [PATCH v10 6/9] pg_ls_*dir to show directories and "isdir" column.. pg_ls_logdir, pg_ls_waldir, pg_ls_archive_statusdir ..FLAG_ISDIR is collapsed into FLAG_METADATA. Need catversion bump --- doc/src/sgml/func.sgml | 39 +++++++++++--------- src/backend/utils/adt/genfile.c | 35 ++++++------------ src/include/catalog/pg_proc.dat | 19 +++++----- src/test/regress/expected/misc_functions.out | 4 +- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 7c73d3b82a..3d8f7dff96 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -21348,8 +21348,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); setof record - List the name, size, and last modification time of files in the log - directory. Access is granted to members of the pg_monitor + For each file in the log directory, list the file's name, size, last + modification time, and a boolean indicating if it is a directory. + Access is granted to members of the pg_monitor role and may be granted to other non-superuser roles. @@ -21359,8 +21360,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); setof record - List the name, size, and last modification time of files in the WAL - directory. Access is granted to members of the pg_monitor + For each file in the WAL directory, list the file's name, size, last + modification time, and a boolean indicating if it is a directory. + Access is granted to members of the pg_monitor role and may be granted to other non-superuser roles. @@ -21370,8 +21372,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); setof record - List the name, size, and last modification time of files in the WAL - archive status directory. Access is granted to members of the + For each file in the WAL archive status directory, list the file's + name, size, last modification time, and a boolean indicating if it is a + directory. Access is granted to members of the pg_monitor role and may be granted to other non-superuser roles. @@ -21446,36 +21449,38 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_ls_logdir - pg_ls_logdir returns the name, size, and last modified time - (mtime) of each file in the log directory. By default, only superusers + pg_ls_logdir lists each file in the log directory, + along with file's size, last modification time, and a boolean + indicating if the file is a directory. By default, only superusers and members of the pg_monitor role can use this function. Access may be granted to others using GRANT. - Filenames beginning with a dot, directories, and other special files are not shown. + Filenames beginning with a dot and special file types are not shown. pg_ls_waldir - pg_ls_waldir returns the name, size, and last modified time - (mtime) of each file in the write ahead log (WAL) directory. By - default only superusers and members of the pg_monitor role + pg_ls_waldir lists each file in the WAL directory, + along with the file's size, last modification time, and a boolean + indicating if the file is a directory. By default, only superusers + and members of the pg_monitor role can use this function. Access may be granted to others using GRANT. - Filenames beginning with a dot, directories, and other special files are not shown. + Filenames beginning with a dot and special file types are not shown. pg_ls_archive_statusdir - pg_ls_archive_statusdir returns the name, size, and - last modified time (mtime) of each file in the WAL archive status - directory pg_wal/archive_status. By default only + pg_ls_archive_statusdir lists each file in the WAL + archive status directory, along with the file's size, last modification + time, and a boolean indicating if the file is a directory. By default, only superusers and members of the pg_monitor role can use this function. Access may be granted to others using GRANT. - Filenames beginning with a dot, directories, and other special files are not shown. + Filenames beginning with a dot and special file types are not shown. diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 5e25e31dff..3ea8c5683e 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -38,13 +38,11 @@ static Datum pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, int flags); -#define FLAG_ISDIR (1<<0) /* Show column: isdir */ -#define FLAG_METADATA (1<<1) /* Show columns: mtime, size */ -#define FLAG_MISSING_OK (1<<2) /* Ignore ENOENT if the toplevel dir is missing */ -#define FLAG_SKIP_DOT_DIRS (1<<3) /* Do not show . or .. */ -#define FLAG_SKIP_HIDDEN (1<<4) /* Do not show anything begining with . */ -#define FLAG_SKIP_DIRS (1<<5) /* Do not show directories */ -#define FLAG_SKIP_SPECIAL (1<<6) /* Do not show special file types */ +#define FLAG_METADATA (1<<0) /* Show columns: mtime, size */ +#define FLAG_MISSING_OK (1<<1) /* Ignore ENOENT if the toplevel dir is missing */ +#define FLAG_SKIP_DOT_DIRS (1<<2) /* Do not show . or .. */ +#define FLAG_SKIP_HIDDEN (1<<3) /* Do not show anything begining with . */ +#define FLAG_SKIP_SPECIAL (1<<4) /* Do not show special file types */ /* * Convert a "text" filename argument to C string, and check it's allowable. @@ -487,11 +485,6 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, int flags) MemoryContext oldcontext; TypeFuncClass tuptype ; - /* isdir depends on metadata */ - Assert(!(flags&FLAG_ISDIR) || (flags&FLAG_METADATA)); - /* Unreasonable to show isdir and skip dirs */ - Assert(!(flags&FLAG_ISDIR) || !(flags&FLAG_SKIP_DIRS)); - /* check the optional arguments */ if (PG_NARGS() == 3) { @@ -589,10 +582,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, int flags) errmsg("could not stat file \"%s\": %m", path))); if (S_ISDIR(attrib.st_mode)) - { - if (flags&FLAG_SKIP_DIRS) - continue; - } + ; /* Do nothing, fall through */ else if (!S_ISREG(attrib.st_mode)) { if (flags&FLAG_SKIP_SPECIAL) @@ -604,8 +594,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, int flags) { values[1] = Int64GetDatum((int64) attrib.st_size); values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime)); - if (flags & FLAG_ISDIR) - values[3] = BoolGetDatum(S_ISDIR(attrib.st_mode)); + values[3] = BoolGetDatum(S_ISDIR(attrib.st_mode)); } memset(nulls, 0, sizeof(nulls)); @@ -623,7 +612,7 @@ Datum pg_ls_logdir(PG_FUNCTION_ARGS) { return pg_ls_dir_files(fcinfo, Log_directory, - FLAG_SKIP_DIRS|FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); + FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); } /* Function to return the list of files in the WAL directory */ @@ -631,7 +620,7 @@ Datum pg_ls_waldir(PG_FUNCTION_ARGS) { return pg_ls_dir_files(fcinfo, XLOGDIR, - FLAG_SKIP_DIRS|FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); + FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); } /* @@ -650,7 +639,7 @@ pg_ls_tmpdir(FunctionCallInfo fcinfo, Oid tblspc) TempTablespacePath(path, tblspc); return pg_ls_dir_files(fcinfo, path, - FLAG_MISSING_OK|FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_ISDIR|FLAG_METADATA); + FLAG_MISSING_OK|FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); } /* @@ -680,7 +669,7 @@ Datum pg_ls_archive_statusdir(PG_FUNCTION_ARGS) { return pg_ls_dir_files(fcinfo, XLOGDIR "/archive_status", - FLAG_MISSING_OK|FLAG_SKIP_DIRS|FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); + FLAG_MISSING_OK|FLAG_SKIP_HIDDEN|FLAG_SKIP_SPECIAL|FLAG_METADATA); } /* @@ -691,5 +680,5 @@ pg_ls_dir_metadata(PG_FUNCTION_ARGS) { char *dirname = convert_and_check_filename(PG_GETARG_TEXT_PP(0)); - return pg_ls_dir_files(fcinfo, dirname, FLAG_METADATA|FLAG_SKIP_SPECIAL|FLAG_ISDIR); + return pg_ls_dir_files(fcinfo, dirname, FLAG_METADATA|FLAG_SKIP_SPECIAL); } diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 7789d029ea..b4c3d15495 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6143,6 +6143,7 @@ proname => 'pg_ls_dir', prorows => '1000', proretset => 't', provolatile => 'v', prorettype => 'text', proargtypes => 'text bool bool', prosrc => 'pg_ls_dir' }, + { oid => '2626', descr => 'sleep for the specified time in seconds', proname => 'pg_sleep', provolatile => 'v', prorettype => 'void', proargtypes => 'float8', prosrc => 'pg_sleep' }, @@ -10717,18 +10718,18 @@ { oid => '3353', descr => 'list files in the log directory', proname => 'pg_ls_logdir', procost => '10', prorows => '20', proretset => 't', provolatile => 'v', prorettype => 'record', proargtypes => '', - proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}', - proargnames => '{name,size,modification}', prosrc => 'pg_ls_logdir' }, + proallargtypes => '{text,int8,timestamptz,bool}', proargmodes => '{o,o,o,o}', + proargnames => '{name,size,modification,isdir}', prosrc => 'pg_ls_logdir' }, { oid => '3354', descr => 'list of files in the WAL directory', proname => 'pg_ls_waldir', procost => '10', prorows => '20', proretset => 't', provolatile => 'v', prorettype => 'record', proargtypes => '', - proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}', - proargnames => '{name,size,modification}', prosrc => 'pg_ls_waldir' }, + proallargtypes => '{text,int8,timestamptz,bool}', proargmodes => '{o,o,o,o}', + proargnames => '{name,size,modification,isdir}', prosrc => 'pg_ls_waldir' }, { oid => '5031', descr => 'list of files in the archive_status directory', proname => 'pg_ls_archive_statusdir', procost => '10', prorows => '20', proretset => 't', provolatile => 'v', prorettype => 'record', - proargtypes => '', proallargtypes => '{text,int8,timestamptz}', - proargmodes => '{o,o,o}', proargnames => '{name,size,modification}', + proargtypes => '', proallargtypes => '{text,int8,timestamptz,bool}', + proargmodes => '{o,o,o,o}', proargnames => '{name,size,modification,isdir}', prosrc => 'pg_ls_archive_statusdir' }, { oid => '5029', descr => 'list files in the pgsql_tmp directory', proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't', @@ -10743,9 +10744,9 @@ prosrc => 'pg_ls_tmpdir_1arg' }, { oid => '5032', descr => 'list directory with metadata', proname => 'pg_ls_dir_metadata', procost => '10', prorows => '20', proretset => 't', - provolatile => 'v', prorettype => 'record', proargtypes => 'text bool bool bool', - proallargtypes => '{text,bool,bool,bool,text,int8,timestamptz,bool}', proargmodes => '{i,i,i,i,o,o,o,o}', - proargnames => '{dirname,missing_ok,include_dot_dirs,dir_ok,name,size,modification,isdir}', + provolatile => 'v', prorettype => 'record', proargtypes => 'text bool bool', + proallargtypes => '{text,bool,bool,text,int8,timestamptz,bool}', proargmodes => '{i,i,i,o,o,o,o}', + proargnames => '{dirname,missing_ok,include_dot_dirs,name,size,modification,isdir}', prosrc => 'pg_ls_dir_metadata' }, # hash partitioning constraint function diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 94b562dcb6..d11b8669c3 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -157,8 +157,8 @@ select count(*) > 0 as ok from (select pg_ls_waldir()) ss; -- Test not-run-to-completion cases. select * from pg_ls_waldir() limit 0; - name | size | modification -------+------+-------------- + name | size | modification | isdir +------+------+--------------+------- (0 rows) select count(*) > 0 as ok from (select * from pg_ls_waldir() limit 1) ss; -- 2.17.0