From bdf72b13775b7fa71d24a92c71fc0c4002109e01 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 29 Jun 2015 15:07:24 +0900 Subject: [PATCH 4/5] Extend pg_tablespace_location with option missing_ok This is useful for code paths that prefer receive an empty response instead of an ERROR if tablespace specified does not exist. --- doc/src/sgml/func.sgml | 9 +++++++-- src/backend/utils/adt/misc.c | 30 ++++++++++++++++++++++++++---- src/include/catalog/pg_proc.h | 2 ++ src/include/utils/builtins.h | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 80a4f26..0257df6 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -15850,9 +15850,14 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); get the set of database OIDs that have objects in the tablespace - pg_tablespace_location(tablespace_oid) + pg_tablespace_location(tablespace_oid [, missing_ok boolean]) text - get the path in the file system that this tablespace is located in + + Get the path in the file system that this tablespace is located in. + If missing_ok is true, the function returns + NULL when the tablespace does not exist. if false, an + error is raised. The default is false. + pg_typeof(any) diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index c0495d9..f5f61c5 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -347,6 +347,10 @@ pg_tablespace_location(PG_FUNCTION_ARGS) char sourcepath[MAXPGPATH]; char targetpath[MAXPGPATH]; int rllen; + bool missing_ok = false; + + if (PG_NARGS() == 2) + missing_ok = PG_GETARG_BOOL(1); /* * It's useful to apply this function to pg_class.reltablespace, wherein @@ -373,10 +377,15 @@ pg_tablespace_location(PG_FUNCTION_ARGS) rllen = readlink(sourcepath, targetpath, sizeof(targetpath)); if (rllen < 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read symbolic link \"%s\": %m", - sourcepath))); + { + if (missing_ok && errno == ENOENT) + PG_RETURN_NULL(); + else + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read symbolic link \"%s\": %m", + sourcepath))); + } if (rllen >= sizeof(targetpath)) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), @@ -394,6 +403,19 @@ pg_tablespace_location(PG_FUNCTION_ARGS) } /* + * pg_tablespace_location (1 argument version) + * + * note: this wrapper is necessary to pass the sanity check in opr_sanity, + * which checks that all built-in functions that share the implementing C + * function take the same number of arguments. + */ +Datum +pg_tablespace_location_1arg(PG_FUNCTION_ARGS) +{ + return pg_tablespace_location(fcinfo); +} + +/* * pg_sleep - delay for N seconds */ Datum diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index f9c6176..6ccbf9b 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -2922,6 +2922,8 @@ DESCR("current trigger depth"); DATA(insert OID = 3778 ( pg_tablespace_location PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_tablespace_location _null_ _null_ _null_ )); DESCR("tablespace location"); +DATA(insert OID = 3579 ( pg_tablespace_location PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "26 16" _null_ _null_ _null_ _null_ _null_ pg_tablespace_location_1arg _null_ _null_ _null_ )); +DESCR("tablespace location"); DATA(insert OID = 1946 ( encode PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "17 25" _null_ _null_ _null_ _null_ _null_ binary_encode _null_ _null_ _null_ )); DESCR("convert bytea value into some ascii-only text string"); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 615e5ab..150afb6 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -490,6 +490,7 @@ extern Datum pg_terminate_backend(PG_FUNCTION_ARGS); extern Datum pg_reload_conf(PG_FUNCTION_ARGS); extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS); extern Datum pg_tablespace_location(PG_FUNCTION_ARGS); +extern Datum pg_tablespace_location_1arg(PG_FUNCTION_ARGS); extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS); extern Datum pg_sleep(PG_FUNCTION_ARGS); extern Datum pg_get_keywords(PG_FUNCTION_ARGS); -- 2.4.5