Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
misc.c File Reference
#include "postgres.h"
#include <sys/file.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <math.h>
#include <unistd.h>
#include "access/sysattr.h"
#include "access/table.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "catalog/system_fk_info.h"
#include "commands/tablespace.h"
#include "common/keywords.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/miscnodes.h"
#include "parser/parse_type.h"
#include "parser/scansup.h"
#include "pgstat.h"
#include "postmaster/syslogger.h"
#include "rewrite/rewriteHandler.h"
#include "storage/fd.h"
#include "storage/latch.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/ruleutils.h"
#include "utils/syscache.h"
#include "utils/timestamp.h"
Include dependency graph for misc.c:

Go to the source code of this file.

Data Structures

struct  ValidIOData
 

Macros

#define REQ_EVENTS   ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
 

Typedefs

typedef struct ValidIOData ValidIOData
 

Functions

static bool pg_input_is_valid_common (FunctionCallInfo fcinfo, text *txt, text *typname, ErrorSaveContext *escontext)
 
static bool count_nulls (FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
 
Datum pg_num_nulls (PG_FUNCTION_ARGS)
 
Datum pg_num_nonnulls (PG_FUNCTION_ARGS)
 
Datum current_database (PG_FUNCTION_ARGS)
 
Datum current_query (PG_FUNCTION_ARGS)
 
Datum pg_tablespace_databases (PG_FUNCTION_ARGS)
 
Datum pg_tablespace_location (PG_FUNCTION_ARGS)
 
Datum pg_sleep (PG_FUNCTION_ARGS)
 
Datum pg_get_keywords (PG_FUNCTION_ARGS)
 
Datum pg_get_catalog_foreign_keys (PG_FUNCTION_ARGS)
 
Datum pg_typeof (PG_FUNCTION_ARGS)
 
Datum pg_basetype (PG_FUNCTION_ARGS)
 
Datum pg_collation_for (PG_FUNCTION_ARGS)
 
Datum pg_relation_is_updatable (PG_FUNCTION_ARGS)
 
Datum pg_column_is_updatable (PG_FUNCTION_ARGS)
 
Datum pg_input_is_valid (PG_FUNCTION_ARGS)
 
Datum pg_input_error_info (PG_FUNCTION_ARGS)
 
static bool is_ident_start (unsigned char c)
 
static bool is_ident_cont (unsigned char c)
 
Datum parse_ident (PG_FUNCTION_ARGS)
 
Datum pg_current_logfile (PG_FUNCTION_ARGS)
 
Datum pg_current_logfile_1arg (PG_FUNCTION_ARGS)
 
Datum pg_get_replica_identity_index (PG_FUNCTION_ARGS)
 
Datum any_value_transfn (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ REQ_EVENTS

#define REQ_EVENTS   ((1 << CMD_UPDATE) | (1 << CMD_DELETE))

Typedef Documentation

◆ ValidIOData

typedef struct ValidIOData ValidIOData

Function Documentation

◆ any_value_transfn()

Datum any_value_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1131 of file misc.c.

1132{
1134}
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353

References PG_GETARG_DATUM, and PG_RETURN_DATUM.

◆ count_nulls()

static bool count_nulls ( FunctionCallInfo  fcinfo,
int32 nargs,
int32 nulls 
)
static

Definition at line 75 of file misc.c.

77{
78 int32 count = 0;
79 int i;
80
81 /* Did we get a VARIADIC array argument, or separate arguments? */
82 if (get_fn_expr_variadic(fcinfo->flinfo))
83 {
84 ArrayType *arr;
85 int ndims,
86 nitems,
87 *dims;
88 bits8 *bitmap;
89
90 Assert(PG_NARGS() == 1);
91
92 /*
93 * If we get a null as VARIADIC array argument, we can't say anything
94 * useful about the number of elements, so return NULL. This behavior
95 * is consistent with other variadic functions - see concat_internal.
96 */
97 if (PG_ARGISNULL(0))
98 return false;
99
100 /*
101 * Non-null argument had better be an array. We assume that any call
102 * context that could let get_fn_expr_variadic return true will have
103 * checked that a VARIADIC-labeled parameter actually is an array. So
104 * it should be okay to just Assert that it's an array rather than
105 * doing a full-fledged error check.
106 */
108
109 /* OK, safe to fetch the array value */
110 arr = PG_GETARG_ARRAYTYPE_P(0);
111
112 /* Count the array elements */
113 ndims = ARR_NDIM(arr);
114 dims = ARR_DIMS(arr);
115 nitems = ArrayGetNItems(ndims, dims);
116
117 /* Count those that are NULL */
118 bitmap = ARR_NULLBITMAP(arr);
119 if (bitmap)
120 {
121 int bitmask = 1;
122
123 for (i = 0; i < nitems; i++)
124 {
125 if ((*bitmap & bitmask) == 0)
126 count++;
127
128 bitmask <<= 1;
129 if (bitmask == 0x100)
130 {
131 bitmap++;
132 bitmask = 1;
133 }
134 }
135 }
136
137 *nargs = nitems;
138 *nulls = count;
139 }
140 else
141 {
142 /* Separate arguments, so just count 'em */
143 for (i = 0; i < PG_NARGS(); i++)
144 {
145 if (PG_ARGISNULL(i))
146 count++;
147 }
148
149 *nargs = PG_NARGS();
150 *nulls = count;
151 }
152
153 return true;
154}
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define ARR_NULLBITMAP(a)
Definition: array.h:300
#define ARR_DIMS(a)
Definition: array.h:294
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
uint8 bits8
Definition: c.h:546
int32_t int32
Definition: c.h:535
#define OidIsValid(objectId)
Definition: c.h:775
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2008
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1874
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_NARGS()
Definition: fmgr.h:203
Assert(PointerIsAligned(start, uint64))
#define nitems(x)
Definition: indent.h:31
int i
Definition: isn.c:77
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2999
FmgrInfo * flinfo
Definition: fmgr.h:87

References ARR_DIMS, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert(), FunctionCallInfoBaseData::flinfo, get_base_element_type(), get_fn_expr_argtype(), get_fn_expr_variadic(), i, nitems, OidIsValid, PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, and PG_NARGS.

Referenced by pg_num_nonnulls(), and pg_num_nulls().

◆ current_database()

Datum current_database ( PG_FUNCTION_ARGS  )

Definition at line 194 of file misc.c.

195{
196 Name db;
197
198 db = (Name) palloc(NAMEDATALEN);
199
201 PG_RETURN_NAME(db);
202}
NameData * Name
Definition: c.h:750
#define PG_RETURN_NAME(x)
Definition: fmgr.h:363
Oid MyDatabaseId
Definition: globals.c:94
char * get_database_name(Oid dbid)
Definition: lsyscache.c:1259
void * palloc(Size size)
Definition: mcxt.c:1365
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define NAMEDATALEN
Definition: c.h:747

References get_database_name(), MyDatabaseId, NAMEDATALEN, namestrcpy(), palloc(), and PG_RETURN_NAME.

Referenced by ExecEvalSQLValueFunction().

◆ current_query()

Datum current_query ( PG_FUNCTION_ARGS  )

Definition at line 211 of file misc.c.

212{
213 /* there is no easy way to access the more concise 'query_string' */
216 else
218}
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
const char * debug_query_string
Definition: postgres.c:88
text * cstring_to_text(const char *s)
Definition: varlena.c:181

References cstring_to_text(), debug_query_string, PG_RETURN_NULL, and PG_RETURN_TEXT_P.

Referenced by dblink_current_query().

◆ is_ident_cont()

static bool is_ident_cont ( unsigned char  c)
static

Definition at line 856 of file misc.c.

857{
858 /* Can be digit or dollar sign ... */
859 if ((c >= '0' && c <= '9') || c == '$')
860 return true;
861 /* ... or an identifier start character */
862 return is_ident_start(c);
863}
static bool is_ident_start(unsigned char c)
Definition: misc.c:838
char * c

References is_ident_start().

Referenced by parse_ident().

◆ is_ident_start()

static bool is_ident_start ( unsigned char  c)
static

Definition at line 838 of file misc.c.

839{
840 /* Underscores and ASCII letters are OK */
841 if (c == '_')
842 return true;
843 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
844 return true;
845 /* Any high-bit-set character is OK (might be part of a multibyte char) */
846 if (IS_HIGHBIT_SET(c))
847 return true;
848 return false;
849}
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1155

References IS_HIGHBIT_SET.

Referenced by is_ident_cont(), and parse_ident().

◆ parse_ident()

Datum parse_ident ( PG_FUNCTION_ARGS  )

Definition at line 871 of file misc.c.

872{
873 text *qualname = PG_GETARG_TEXT_PP(0);
874 bool strict = PG_GETARG_BOOL(1);
875 char *qualname_str = text_to_cstring(qualname);
876 ArrayBuildState *astate = NULL;
877 char *nextp;
878 bool after_dot = false;
879
880 /*
881 * The code below scribbles on qualname_str in some cases, so we should
882 * reconvert qualname if we need to show the original string in error
883 * messages.
884 */
885 nextp = qualname_str;
886
887 /* skip leading whitespace */
888 while (scanner_isspace(*nextp))
889 nextp++;
890
891 for (;;)
892 {
893 char *curname;
894 bool missing_ident = true;
895
896 if (*nextp == '"')
897 {
898 char *endp;
899
900 curname = nextp + 1;
901 for (;;)
902 {
903 endp = strchr(nextp + 1, '"');
904 if (endp == NULL)
906 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
907 errmsg("string is not a valid identifier: \"%s\"",
908 text_to_cstring(qualname)),
909 errdetail("String has unclosed double quotes.")));
910 if (endp[1] != '"')
911 break;
912 memmove(endp, endp + 1, strlen(endp));
913 nextp = endp;
914 }
915 nextp = endp + 1;
916 *endp = '\0';
917
918 if (endp - curname == 0)
920 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
921 errmsg("string is not a valid identifier: \"%s\"",
922 text_to_cstring(qualname)),
923 errdetail("Quoted identifier must not be empty.")));
924
925 astate = accumArrayResult(astate, CStringGetTextDatum(curname),
926 false, TEXTOID, CurrentMemoryContext);
927 missing_ident = false;
928 }
929 else if (is_ident_start((unsigned char) *nextp))
930 {
931 char *downname;
932 int len;
933 text *part;
934
935 curname = nextp++;
936 while (is_ident_cont((unsigned char) *nextp))
937 nextp++;
938
939 len = nextp - curname;
940
941 /*
942 * We don't implicitly truncate identifiers. This is useful for
943 * allowing the user to check for specific parts of the identifier
944 * being too long. It's easy enough for the user to get the
945 * truncated names by casting our output to name[].
946 */
947 downname = downcase_identifier(curname, len, false, false);
948 part = cstring_to_text_with_len(downname, len);
949 astate = accumArrayResult(astate, PointerGetDatum(part), false,
950 TEXTOID, CurrentMemoryContext);
951 missing_ident = false;
952 }
953
954 if (missing_ident)
955 {
956 /* Different error messages based on where we failed. */
957 if (*nextp == '.')
959 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
960 errmsg("string is not a valid identifier: \"%s\"",
961 text_to_cstring(qualname)),
962 errdetail("No valid identifier before \".\".")));
963 else if (after_dot)
965 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
966 errmsg("string is not a valid identifier: \"%s\"",
967 text_to_cstring(qualname)),
968 errdetail("No valid identifier after \".\".")));
969 else
971 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
972 errmsg("string is not a valid identifier: \"%s\"",
973 text_to_cstring(qualname))));
974 }
975
976 while (scanner_isspace(*nextp))
977 nextp++;
978
979 if (*nextp == '.')
980 {
981 after_dot = true;
982 nextp++;
983 while (scanner_isspace(*nextp))
984 nextp++;
985 }
986 else if (*nextp == '\0')
987 {
988 break;
989 }
990 else
991 {
992 if (strict)
994 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
995 errmsg("string is not a valid identifier: \"%s\"",
996 text_to_cstring(qualname))));
997 break;
998 }
999 }
1000
1002}
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5350
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5420
static bool is_ident_cont(unsigned char c)
Definition: misc.c:856
#define CStringGetTextDatum(s)
Definition: builtins.h:97
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
const void size_t len
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition: scansup.c:46
bool scanner_isspace(char ch)
Definition: scansup.c:117
Definition: c.h:693
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:193
char * text_to_cstring(const text *t)
Definition: varlena.c:214

References accumArrayResult(), cstring_to_text_with_len(), CStringGetTextDatum, CurrentMemoryContext, downcase_identifier(), ereport, errcode(), errdetail(), errmsg(), ERROR, is_ident_cont(), is_ident_start(), len, makeArrayResult(), PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_DATUM, PointerGetDatum(), scanner_isspace(), and text_to_cstring().

◆ pg_basetype()

Datum pg_basetype ( PG_FUNCTION_ARGS  )

Definition at line 593 of file misc.c.

594{
595 Oid typid = PG_GETARG_OID(0);
596
597 /*
598 * We loop to find the bottom base type in a stack of domains.
599 */
600 for (;;)
601 {
602 HeapTuple tup;
603 Form_pg_type typTup;
604
605 tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
606 if (!HeapTupleIsValid(tup))
607 PG_RETURN_NULL(); /* return NULL for bogus OID */
608 typTup = (Form_pg_type) GETSTRUCT(tup);
609 if (typTup->typtype != TYPTYPE_DOMAIN)
610 {
611 /* Not a domain, so done */
612 ReleaseSysCache(tup);
613 break;
614 }
615
616 typid = typTup->typbasetype;
617 ReleaseSysCache(tup);
618 }
619
620 PG_RETURN_OID(typid);
621}
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
unsigned int Oid
Definition: postgres_ext.h:32
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220

References GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_OID, ReleaseSysCache(), and SearchSysCache1().

◆ pg_collation_for()

Datum pg_collation_for ( PG_FUNCTION_ARGS  )

Definition at line 629 of file misc.c.

630{
631 Oid typeid;
632 Oid collid;
633
634 typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
635 if (!typeid)
637 if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
639 (errcode(ERRCODE_DATATYPE_MISMATCH),
640 errmsg("collations are not supported by type %s",
641 format_type_be(typeid))));
642
644 if (!collid)
647}
Oid collid
#define PG_GET_COLLATION()
Definition: fmgr.h:198
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:3248
char * generate_collation_name(Oid collid)
Definition: ruleutils.c:13546

References collid, cstring_to_text(), ereport, errcode(), errmsg(), ERROR, format_type_be(), generate_collation_name(), get_fn_expr_argtype(), PG_GET_COLLATION, PG_RETURN_NULL, PG_RETURN_TEXT_P, and type_is_collatable().

◆ pg_column_is_updatable()

Datum pg_column_is_updatable ( PG_FUNCTION_ARGS  )

Definition at line 675 of file misc.c.

676{
677 Oid reloid = PG_GETARG_OID(0);
680 bool include_triggers = PG_GETARG_BOOL(2);
681 int events;
682
683 /* System columns are never updatable */
684 if (attnum <= 0)
685 PG_RETURN_BOOL(false);
686
687 events = relation_is_updatable(reloid, NIL, include_triggers,
688 bms_make_singleton(col));
689
690 /* We require both updatability and deletability of the relation */
691#define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
692
693 PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
694}
int16 AttrNumber
Definition: attnum.h:21
#define REQ_EVENTS
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:216
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_INT16(n)
Definition: fmgr.h:271
int16 attnum
Definition: pg_attribute.h:74
#define NIL
Definition: pg_list.h:68
int relation_is_updatable(Oid reloid, List *outer_reloids, bool include_triggers, Bitmapset *include_cols)
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27

References attnum, bms_make_singleton(), FirstLowInvalidHeapAttributeNumber, NIL, PG_GETARG_BOOL, PG_GETARG_INT16, PG_GETARG_OID, PG_RETURN_BOOL, relation_is_updatable(), and REQ_EVENTS.

◆ pg_current_logfile()

Datum pg_current_logfile ( PG_FUNCTION_ARGS  )

Definition at line 1010 of file misc.c.

1011{
1012 FILE *fd;
1013 char lbuffer[MAXPGPATH];
1014 char *logfmt;
1015
1016 /* The log format parameter is optional */
1017 if (PG_NARGS() == 0 || PG_ARGISNULL(0))
1018 logfmt = NULL;
1019 else
1020 {
1022
1023 if (strcmp(logfmt, "stderr") != 0 &&
1024 strcmp(logfmt, "csvlog") != 0 &&
1025 strcmp(logfmt, "jsonlog") != 0)
1026 ereport(ERROR,
1027 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1028 errmsg("log format \"%s\" is not supported", logfmt),
1029 errhint("The supported log formats are \"stderr\", \"csvlog\", and \"jsonlog\".")));
1030 }
1031
1033 if (fd == NULL)
1034 {
1035 if (errno != ENOENT)
1036 ereport(ERROR,
1038 errmsg("could not read file \"%s\": %m",
1041 }
1042
1043#ifdef WIN32
1044 /* syslogger.c writes CRLF line endings on Windows */
1045 _setmode(_fileno(fd), _O_TEXT);
1046#endif
1047
1048 /*
1049 * Read the file to gather current log filename(s) registered by the
1050 * syslogger.
1051 */
1052 while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
1053 {
1054 char *log_format;
1055 char *log_filepath;
1056 char *nlpos;
1057
1058 /* Extract log format and log file path from the line. */
1059 log_format = lbuffer;
1060 log_filepath = strchr(lbuffer, ' ');
1061 if (log_filepath == NULL)
1062 {
1063 /* Uh oh. No space found, so file content is corrupted. */
1064 elog(ERROR,
1065 "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
1066 break;
1067 }
1068
1069 *log_filepath = '\0';
1070 log_filepath++;
1071 nlpos = strchr(log_filepath, '\n');
1072 if (nlpos == NULL)
1073 {
1074 /* Uh oh. No newline found, so file content is corrupted. */
1075 elog(ERROR,
1076 "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
1077 break;
1078 }
1079 *nlpos = '\0';
1080
1081 if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
1082 {
1083 FreeFile(fd);
1084 PG_RETURN_TEXT_P(cstring_to_text(log_filepath));
1085 }
1086 }
1087
1088 /* Close the current log filename file. */
1089 FreeFile(fd);
1090
1092}
int errcode_for_file_access(void)
Definition: elog.c:877
int errhint(const char *fmt,...)
Definition: elog.c:1321
#define elog(elevel,...)
Definition: elog.h:226
int FreeFile(FILE *file)
Definition: fd.c:2840
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2641
#define MAXPGPATH
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define LOG_METAINFO_DATAFILE
Definition: syslogger.h:102

References AllocateFile(), cstring_to_text(), elog, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, fd(), FreeFile(), LOG_METAINFO_DATAFILE, MAXPGPATH, PG_ARGISNULL, PG_GETARG_TEXT_PP, PG_NARGS, PG_RETURN_NULL, PG_RETURN_TEXT_P, and text_to_cstring().

Referenced by pg_current_logfile_1arg().

◆ pg_current_logfile_1arg()

Datum pg_current_logfile_1arg ( PG_FUNCTION_ARGS  )

Definition at line 1102 of file misc.c.

1103{
1104 return pg_current_logfile(fcinfo);
1105}
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition: misc.c:1010

References pg_current_logfile().

◆ pg_get_catalog_foreign_keys()

Datum pg_get_catalog_foreign_keys ( PG_FUNCTION_ARGS  )

Definition at line 506 of file misc.c.

507{
508 FuncCallContext *funcctx;
509 FmgrInfo *arrayinp;
510
511 if (SRF_IS_FIRSTCALL())
512 {
513 MemoryContext oldcontext;
514 TupleDesc tupdesc;
515
516 funcctx = SRF_FIRSTCALL_INIT();
517 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
518
519 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
520 elog(ERROR, "return type must be a row type");
521 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
522
523 /*
524 * We use array_in to convert the C strings in sys_fk_relationships[]
525 * to text arrays. But we cannot use DirectFunctionCallN to call
526 * array_in, and it wouldn't be very efficient if we could. Fill an
527 * FmgrInfo to use for the call.
528 */
529 arrayinp = (FmgrInfo *) palloc(sizeof(FmgrInfo));
530 fmgr_info(F_ARRAY_IN, arrayinp);
531 funcctx->user_fctx = arrayinp;
532
533 MemoryContextSwitchTo(oldcontext);
534 }
535
536 funcctx = SRF_PERCALL_SETUP();
537 arrayinp = (FmgrInfo *) funcctx->user_fctx;
538
539 if (funcctx->call_cntr < lengthof(sys_fk_relationships))
540 {
541 const SysFKRelationship *fkrel = &sys_fk_relationships[funcctx->call_cntr];
542 Datum values[6];
543 bool nulls[6];
544 HeapTuple tuple;
545
546 memset(nulls, false, sizeof(nulls));
547
548 values[0] = ObjectIdGetDatum(fkrel->fk_table);
549 values[1] = FunctionCall3(arrayinp,
550 CStringGetDatum(fkrel->fk_columns),
551 ObjectIdGetDatum(TEXTOID),
552 Int32GetDatum(-1));
553 values[2] = ObjectIdGetDatum(fkrel->pk_table);
554 values[3] = FunctionCall3(arrayinp,
555 CStringGetDatum(fkrel->pk_columns),
556 ObjectIdGetDatum(TEXTOID),
557 Int32GetDatum(-1));
558 values[4] = BoolGetDatum(fkrel->is_array);
559 values[5] = BoolGetDatum(fkrel->is_opt);
560
561 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
562
563 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
564 }
565
566 SRF_RETURN_DONE(funcctx);
567}
static Datum values[MAXATTR]
Definition: bootstrap.c:153
#define lengthof(array)
Definition: c.h:788
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2260
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
#define FunctionCall3(flinfo, arg1, arg2, arg3)
Definition: fmgr.h:704
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static Datum BoolGetDatum(bool X)
Definition: postgres.h:112
uint64_t Datum
Definition: postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:360
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
Definition: fmgr.h:57
void * user_fctx
Definition: funcapi.h:82
uint64 call_cntr
Definition: funcapi.h:65
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
TupleDesc tuple_desc
Definition: funcapi.h:112

References BlessTupleDesc(), BoolGetDatum(), FuncCallContext::call_cntr, CStringGetDatum(), elog, ERROR, fmgr_info(), FunctionCall3, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum(), if(), Int32GetDatum(), lengthof, MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, ObjectIdGetDatum(), palloc(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, FuncCallContext::tuple_desc, TYPEFUNC_COMPOSITE, FuncCallContext::user_fctx, and values.

◆ pg_get_keywords()

Datum pg_get_keywords ( PG_FUNCTION_ARGS  )

Definition at line 428 of file misc.c.

429{
430 FuncCallContext *funcctx;
431
432 if (SRF_IS_FIRSTCALL())
433 {
434 MemoryContext oldcontext;
435 TupleDesc tupdesc;
436
437 funcctx = SRF_FIRSTCALL_INIT();
438 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
439
440 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
441 elog(ERROR, "return type must be a row type");
442 funcctx->tuple_desc = tupdesc;
443 funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
444
445 MemoryContextSwitchTo(oldcontext);
446 }
447
448 funcctx = SRF_PERCALL_SETUP();
449
450 if (funcctx->call_cntr < ScanKeywords.num_keywords)
451 {
452 char *values[5];
453 HeapTuple tuple;
454
455 /* cast-away-const is ugly but alternatives aren't much better */
456 values[0] = unconstify(char *,
457 GetScanKeyword(funcctx->call_cntr,
458 &ScanKeywords));
459
460 switch (ScanKeywordCategories[funcctx->call_cntr])
461 {
463 values[1] = "U";
464 values[3] = _("unreserved");
465 break;
466 case COL_NAME_KEYWORD:
467 values[1] = "C";
468 values[3] = _("unreserved (cannot be function or type name)");
469 break;
471 values[1] = "T";
472 values[3] = _("reserved (can be function or type name)");
473 break;
474 case RESERVED_KEYWORD:
475 values[1] = "R";
476 values[3] = _("reserved");
477 break;
478 default: /* shouldn't be possible */
479 values[1] = NULL;
480 values[3] = NULL;
481 break;
482 }
483
484 if (ScanKeywordBareLabel[funcctx->call_cntr])
485 {
486 values[2] = "true";
487 values[4] = _("can be bare label");
488 }
489 else
490 {
491 values[2] = "false";
492 values[4] = _("requires AS");
493 }
494
495 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
496
497 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
498 }
499
500 SRF_RETURN_DONE(funcctx);
501}
#define unconstify(underlying_type, expr)
Definition: c.h:1245
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:29
const bool ScanKeywordBareLabel[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:42
#define _(x)
Definition: elog.c:91
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:2324
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2275
PGDLLIMPORT const ScanKeywordList ScanKeywords
#define COL_NAME_KEYWORD
Definition: keywords.h:21
#define UNRESERVED_KEYWORD
Definition: keywords.h:20
#define TYPE_FUNC_NAME_KEYWORD
Definition: keywords.h:22
#define RESERVED_KEYWORD
Definition: keywords.h:23
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition: kwlookup.h:39
AttInMetadata * attinmeta
Definition: funcapi.h:91
int num_keywords
Definition: kwlookup.h:30

References _, FuncCallContext::attinmeta, BuildTupleFromCStrings(), FuncCallContext::call_cntr, COL_NAME_KEYWORD, elog, ERROR, get_call_result_type(), GetScanKeyword(), HeapTupleGetDatum(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, ScanKeywordList::num_keywords, RESERVED_KEYWORD, ScanKeywordBareLabel, ScanKeywordCategories, ScanKeywords, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, FuncCallContext::tuple_desc, TupleDescGetAttInMetadata(), TYPE_FUNC_NAME_KEYWORD, TYPEFUNC_COMPOSITE, unconstify, UNRESERVED_KEYWORD, and values.

◆ pg_get_replica_identity_index()

Datum pg_get_replica_identity_index ( PG_FUNCTION_ARGS  )

Definition at line 1111 of file misc.c.

1112{
1113 Oid reloid = PG_GETARG_OID(0);
1114 Oid idxoid;
1115 Relation rel;
1116
1117 rel = table_open(reloid, AccessShareLock);
1118 idxoid = RelationGetReplicaIndex(rel);
1120
1121 if (OidIsValid(idxoid))
1122 PG_RETURN_OID(idxoid);
1123 else
1125}
#define AccessShareLock
Definition: lockdefs.h:36
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:5072
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, OidIsValid, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_OID, RelationGetReplicaIndex(), table_close(), and table_open().

◆ pg_input_error_info()

Datum pg_input_error_info ( PG_FUNCTION_ARGS  )

Definition at line 726 of file misc.c.

727{
728 text *txt = PG_GETARG_TEXT_PP(0);
730 ErrorSaveContext escontext = {T_ErrorSaveContext};
731 TupleDesc tupdesc;
732 Datum values[4];
733 bool isnull[4];
734
735 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
736 elog(ERROR, "return type must be a row type");
737
738 /* Enable details_wanted */
739 escontext.details_wanted = true;
740
741 if (pg_input_is_valid_common(fcinfo, txt, typname,
742 &escontext))
743 memset(isnull, true, sizeof(isnull));
744 else
745 {
746 char *sqlstate;
747
748 Assert(escontext.error_occurred);
749 Assert(escontext.error_data != NULL);
750 Assert(escontext.error_data->message != NULL);
751
752 memset(isnull, false, sizeof(isnull));
753
755
756 if (escontext.error_data->detail != NULL)
758 else
759 isnull[1] = true;
760
761 if (escontext.error_data->hint != NULL)
762 values[2] = CStringGetTextDatum(escontext.error_data->hint);
763 else
764 isnull[2] = true;
765
766 sqlstate = unpack_sql_state(escontext.error_data->sqlerrcode);
767 values[3] = CStringGetTextDatum(sqlstate);
768 }
769
770 return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
771}
static bool pg_input_is_valid_common(FunctionCallInfo fcinfo, text *txt, text *typname, ErrorSaveContext *escontext)
Definition: misc.c:775
char * unpack_sql_state(int sql_state)
Definition: elog.c:3213
NameData typname
Definition: pg_type.h:41
int sqlerrcode
Definition: elog.h:431
char * detail
Definition: elog.h:433
char * message
Definition: elog.h:432
char * hint
Definition: elog.h:435
bool details_wanted
Definition: miscnodes.h:48
ErrorData * error_data
Definition: miscnodes.h:49
bool error_occurred
Definition: miscnodes.h:47

References Assert(), CStringGetTextDatum, ErrorData::detail, ErrorSaveContext::details_wanted, elog, ERROR, ErrorSaveContext::error_data, ErrorSaveContext::error_occurred, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum(), ErrorData::hint, ErrorData::message, PG_GETARG_TEXT_PP, pg_input_is_valid_common(), ErrorData::sqlerrcode, TYPEFUNC_COMPOSITE, typname, unpack_sql_state(), and values.

◆ pg_input_is_valid()

Datum pg_input_is_valid ( PG_FUNCTION_ARGS  )

Definition at line 706 of file misc.c.

707{
708 text *txt = PG_GETARG_TEXT_PP(0);
710 ErrorSaveContext escontext = {T_ErrorSaveContext};
711
713 &escontext));
714}

References PG_GETARG_TEXT_PP, pg_input_is_valid_common(), PG_RETURN_BOOL, and typname.

◆ pg_input_is_valid_common()

static bool pg_input_is_valid_common ( FunctionCallInfo  fcinfo,
text txt,
text typname,
ErrorSaveContext escontext 
)
static

Definition at line 775 of file misc.c.

778{
779 char *str = text_to_cstring(txt);
780 ValidIOData *my_extra;
781 Datum converted;
782
783 /*
784 * We arrange to look up the needed I/O info just once per series of
785 * calls, assuming the data type doesn't change underneath us.
786 */
787 my_extra = (ValidIOData *) fcinfo->flinfo->fn_extra;
788 if (my_extra == NULL)
789 {
790 fcinfo->flinfo->fn_extra =
792 sizeof(ValidIOData));
793 my_extra = (ValidIOData *) fcinfo->flinfo->fn_extra;
794 my_extra->typoid = InvalidOid;
795 /* Detect whether typname argument is constant. */
796 my_extra->typname_constant = get_fn_expr_arg_stable(fcinfo->flinfo, 1);
797 }
798
799 /*
800 * If the typname argument is constant, we only need to parse it the first
801 * time through.
802 */
803 if (my_extra->typoid == InvalidOid || !my_extra->typname_constant)
804 {
805 char *typnamestr = text_to_cstring(typname);
806 Oid typoid;
807
808 /* Parse type-name argument to obtain type OID and encoded typmod. */
809 (void) parseTypeString(typnamestr, &typoid, &my_extra->typmod, NULL);
810
811 /* Update type-specific info if typoid changed. */
812 if (my_extra->typoid != typoid)
813 {
814 getTypeInputInfo(typoid,
815 &my_extra->typiofunc,
816 &my_extra->typioparam);
817 fmgr_info_cxt(my_extra->typiofunc, &my_extra->inputproc,
818 fcinfo->flinfo->fn_mcxt);
819 my_extra->typoid = typoid;
820 }
821 }
822
823 /* Now we can try to perform the conversion. */
824 return InputFunctionCallSafe(&my_extra->inputproc,
825 str,
826 my_extra->typioparam,
827 my_extra->typmod,
828 (Node *) escontext,
829 &converted);
830}
bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1939
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
Definition: fmgr.c:1584
const char * str
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:3041
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1229
bool parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, Node *escontext)
Definition: parse_type.c:785
#define InvalidOid
Definition: postgres_ext.h:37
void * fn_extra
Definition: fmgr.h:64
MemoryContext fn_mcxt
Definition: fmgr.h:65
Definition: nodes.h:135
int32 typmod
Definition: misc.c:56
Oid typoid
Definition: misc.c:55
bool typname_constant
Definition: misc.c:57
FmgrInfo inputproc
Definition: misc.c:60
Oid typiofunc
Definition: misc.c:58
Oid typioparam
Definition: misc.c:59

References FunctionCallInfoBaseData::flinfo, fmgr_info_cxt(), FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, get_fn_expr_arg_stable(), getTypeInputInfo(), if(), InputFunctionCallSafe(), ValidIOData::inputproc, InvalidOid, MemoryContextAlloc(), parseTypeString(), str, text_to_cstring(), ValidIOData::typiofunc, ValidIOData::typioparam, ValidIOData::typmod, typname, ValidIOData::typname_constant, and ValidIOData::typoid.

Referenced by pg_input_error_info(), and pg_input_is_valid().

◆ pg_num_nonnulls()

Datum pg_num_nonnulls ( PG_FUNCTION_ARGS  )

Definition at line 177 of file misc.c.

178{
179 int32 nargs,
180 nulls;
181
182 if (!count_nulls(fcinfo, &nargs, &nulls))
184
185 PG_RETURN_INT32(nargs - nulls);
186}
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition: misc.c:75
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

◆ pg_num_nulls()

Datum pg_num_nulls ( PG_FUNCTION_ARGS  )

Definition at line 161 of file misc.c.

162{
163 int32 nargs,
164 nulls;
165
166 if (!count_nulls(fcinfo, &nargs, &nulls))
168
169 PG_RETURN_INT32(nulls);
170}

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

◆ pg_relation_is_updatable()

Datum pg_relation_is_updatable ( PG_FUNCTION_ARGS  )

Definition at line 658 of file misc.c.

659{
660 Oid reloid = PG_GETARG_OID(0);
661 bool include_triggers = PG_GETARG_BOOL(1);
662
663 PG_RETURN_INT32(relation_is_updatable(reloid, NIL, include_triggers, NULL));
664}

References NIL, PG_GETARG_BOOL, PG_GETARG_OID, PG_RETURN_INT32, and relation_is_updatable().

◆ pg_sleep()

Datum pg_sleep ( PG_FUNCTION_ARGS  )

Definition at line 369 of file misc.c.

370{
371 float8 secs = PG_GETARG_FLOAT8(0);
372 int64 usecs;
373 TimestampTz endtime;
374
375 /*
376 * Convert the delay to int64 microseconds, rounding up any fraction, and
377 * silently limiting it to PG_INT64_MAX/2 microseconds (about 150K years)
378 * to ensure the computation of endtime won't overflow. Historically
379 * we've treated NaN as "no wait", not an error, so keep that behavior.
380 */
381 if (isnan(secs) || secs <= 0.0)
383 secs *= USECS_PER_SEC; /* we assume overflow will produce +Inf */
384 secs = ceil(secs); /* round up any fractional microsecond */
385 usecs = (int64) Min(secs, (float8) (PG_INT64_MAX / 2));
386
387 /*
388 * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
389 * important signal (such as SIGALRM or SIGINT) arrives. Because
390 * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
391 * might ask for more than that, we sleep for at most 10 minutes and then
392 * loop.
393 *
394 * By computing the intended stop time initially, we avoid accumulation of
395 * extra delay across multiple sleeps. This also ensures we won't delay
396 * less than the specified time when WaitLatch is terminated early by a
397 * non-query-canceling signal such as SIGHUP.
398 */
399 endtime = GetCurrentTimestamp() + usecs;
400
401 for (;;)
402 {
403 TimestampTz delay;
404 long delay_ms;
405
407
408 delay = endtime - GetCurrentTimestamp();
409 if (delay >= 600 * USECS_PER_SEC)
410 delay_ms = 600000;
411 else if (delay > 0)
412 delay_ms = (long) ((delay + 999) / 1000);
413 else
414 break;
415
416 (void) WaitLatch(MyLatch,
418 delay_ms,
419 WAIT_EVENT_PG_SLEEP);
421 }
422
424}
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
#define Min(x, y)
Definition: c.h:1004
int64_t int64
Definition: c.h:536
double float8
Definition: c.h:636
#define PG_INT64_MAX
Definition: c.h:598
int64 TimestampTz
Definition: timestamp.h:39
#define USECS_PER_SEC
Definition: timestamp.h:134
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
struct Latch * MyLatch
Definition: globals.c:63
void ResetLatch(Latch *latch)
Definition: latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define WL_LATCH_SET
Definition: waiteventset.h:34

References CHECK_FOR_INTERRUPTS, GetCurrentTimestamp(), Min, MyLatch, PG_GETARG_FLOAT8, PG_INT64_MAX, PG_RETURN_VOID, ResetLatch(), USECS_PER_SEC, WaitLatch(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_TIMEOUT.

◆ pg_tablespace_databases()

Datum pg_tablespace_databases ( PG_FUNCTION_ARGS  )

Definition at line 223 of file misc.c.

224{
225 Oid tablespaceOid = PG_GETARG_OID(0);
226 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
227 char *location;
228 DIR *dirdesc;
229 struct dirent *de;
230
232
233 if (tablespaceOid == GLOBALTABLESPACE_OID)
234 {
236 (errmsg("global tablespace never has databases")));
237 /* return empty tuplestore */
238 return (Datum) 0;
239 }
240
241 if (tablespaceOid == DEFAULTTABLESPACE_OID)
242 location = "base";
243 else
244 location = psprintf("%s/%u/%s", PG_TBLSPC_DIR, tablespaceOid,
246
247 dirdesc = AllocateDir(location);
248
249 if (!dirdesc)
250 {
251 /* the only expected error is ENOENT */
252 if (errno != ENOENT)
255 errmsg("could not open directory \"%s\": %m",
256 location)));
258 (errmsg("%u is not a tablespace OID", tablespaceOid)));
259 /* return empty tuplestore */
260 return (Datum) 0;
261 }
262
263 while ((de = ReadDir(dirdesc, location)) != NULL)
264 {
265 Oid datOid = atooid(de->d_name);
266 char *subdir;
267 bool isempty;
268 Datum values[1];
269 bool nulls[1];
270
271 /* this test skips . and .., but is awfully weak */
272 if (!datOid)
273 continue;
274
275 /* if database subdir is empty, don't report tablespace as used */
276
277 subdir = psprintf("%s/%s", location, de->d_name);
278 isempty = directory_is_empty(subdir);
279 pfree(subdir);
280
281 if (isempty)
282 continue; /* indeed, nothing in it */
283
284 values[0] = ObjectIdGetDatum(datOid);
285 nulls[0] = false;
286
287 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
288 values, nulls);
289 }
290
291 FreeDir(dirdesc);
292 return (Datum) 0;
293}
bool directory_is_empty(const char *path)
Definition: tablespace.c:853
#define WARNING
Definition: elog.h:36
int FreeDir(DIR *dir)
Definition: fd.c:3022
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2904
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2970
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition: funcapi.h:296
void pfree(void *pointer)
Definition: mcxt.c:1594
#define atooid(x)
Definition: postgres_ext.h:43
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
#define PG_TBLSPC_DIR
Definition: relpath.h:41
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:33
Definition: dirent.c:26
TupleDesc setDesc
Definition: execnodes.h:364
Tuplestorestate * setResult
Definition: execnodes.h:363
Definition: dirent.h:10
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784

References AllocateDir(), atooid, directory_is_empty(), ereport, errcode_for_file_access(), errmsg(), ERROR, FreeDir(), InitMaterializedSRF(), MAT_SRF_USE_EXPECTED_DESC, ObjectIdGetDatum(), pfree(), PG_GETARG_OID, PG_TBLSPC_DIR, psprintf(), ReadDir(), ReturnSetInfo::setDesc, ReturnSetInfo::setResult, TABLESPACE_VERSION_DIRECTORY, tuplestore_putvalues(), values, and WARNING.

◆ pg_tablespace_location()

Datum pg_tablespace_location ( PG_FUNCTION_ARGS  )

Definition at line 300 of file misc.c.

301{
302 Oid tablespaceOid = PG_GETARG_OID(0);
303 char sourcepath[MAXPGPATH];
304 char targetpath[MAXPGPATH];
305 int rllen;
306 struct stat st;
307
308 /*
309 * It's useful to apply this function to pg_class.reltablespace, wherein
310 * zero means "the database's default tablespace". So, rather than
311 * throwing an error for zero, we choose to assume that's what is meant.
312 */
313 if (tablespaceOid == InvalidOid)
314 tablespaceOid = MyDatabaseTableSpace;
315
316 /*
317 * Return empty string for the cluster's default tablespaces
318 */
319 if (tablespaceOid == DEFAULTTABLESPACE_OID ||
320 tablespaceOid == GLOBALTABLESPACE_OID)
322
323 /*
324 * Find the location of the tablespace by reading the symbolic link that
325 * is in pg_tblspc/<oid>.
326 */
327 snprintf(sourcepath, sizeof(sourcepath), "%s/%u", PG_TBLSPC_DIR, tablespaceOid);
328
329 /*
330 * Before reading the link, check if the source path is a link or a
331 * junction point. Note that a directory is possible for a tablespace
332 * created with allow_in_place_tablespaces enabled. If a directory is
333 * found, a relative path to the data directory is returned.
334 */
335 if (lstat(sourcepath, &st) < 0)
336 {
339 errmsg("could not stat file \"%s\": %m",
340 sourcepath)));
341 }
342
343 if (!S_ISLNK(st.st_mode))
345
346 /*
347 * In presence of a link or a junction point, return the path pointing to.
348 */
349 rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
350 if (rllen < 0)
353 errmsg("could not read symbolic link \"%s\": %m",
354 sourcepath)));
355 if (rllen >= sizeof(targetpath))
357 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
358 errmsg("symbolic link \"%s\" target is too long",
359 sourcepath)));
360 targetpath[rllen] = '\0';
361
363}
Oid MyDatabaseTableSpace
Definition: globals.c:96
#define snprintf
Definition: port.h:239
#define lstat(path, sb)
Definition: win32_port.h:275
#define S_ISLNK(m)
Definition: win32_port.h:334
#define readlink(path, buf, size)
Definition: win32_port.h:226

References cstring_to_text(), ereport, errcode(), errcode_for_file_access(), errmsg(), ERROR, InvalidOid, lstat, MAXPGPATH, MyDatabaseTableSpace, PG_GETARG_OID, PG_RETURN_TEXT_P, PG_TBLSPC_DIR, readlink, S_ISLNK, snprintf, and stat::st_mode.

◆ pg_typeof()

Datum pg_typeof ( PG_FUNCTION_ARGS  )

Definition at line 574 of file misc.c.

575{
576 PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
577}

References get_fn_expr_argtype(), and PG_RETURN_OID.