PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/htup_details.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 "utils/tuplestore.h"
#include "utils/wait_event.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 pg_error_on_null (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

Function Documentation

◆ any_value_transfn()

Datum any_value_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1094 of file misc.c.

1095{
1097}
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354

References PG_GETARG_DATUM, and PG_RETURN_DATUM.

◆ count_nulls()

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

Definition at line 78 of file misc.c.

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

212{
213 Name db;
214
215 db = (Name) palloc(NAMEDATALEN);
216
218 PG_RETURN_NAME(db);
219}
NameData * Name
Definition c.h:833
#define PG_RETURN_NAME(x)
Definition fmgr.h:365
Oid MyDatabaseId
Definition globals.c:94
char * get_database_name(Oid dbid)
Definition lsyscache.c:1312
void * palloc(Size size)
Definition mcxt.c:1387
void namestrcpy(Name name, const char *str)
Definition name.c:233
#define NAMEDATALEN
Definition c.h:830

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 228 of file misc.c.

229{
230 /* there is no easy way to access the more concise 'query_string' */
233 else
235}
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
const char * debug_query_string
Definition postgres.c:91
text * cstring_to_text(const char *s)
Definition varlena.c:184

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 819 of file misc.c.

820{
821 /* Can be digit or dollar sign ... */
822 if ((c >= '0' && c <= '9') || c == '$')
823 return true;
824 /* ... or an identifier start character */
825 return is_ident_start(c);
826}
static bool is_ident_start(unsigned char c)
Definition misc.c:801
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 801 of file misc.c.

802{
803 /* Underscores and ASCII letters are OK */
804 if (c == '_')
805 return true;
806 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
807 return true;
808 /* Any high-bit-set character is OK (might be part of a multibyte char) */
809 if (IS_HIGHBIT_SET(c))
810 return true;
811 return false;
812}
#define IS_HIGHBIT_SET(ch)
Definition c.h:1244

References IS_HIGHBIT_SET.

Referenced by is_ident_cont(), and parse_ident().

◆ parse_ident()

Datum parse_ident ( PG_FUNCTION_ARGS  )

Definition at line 834 of file misc.c.

835{
837 bool strict = PG_GETARG_BOOL(1);
839 ArrayBuildState *astate = NULL;
840 char *nextp;
841 bool after_dot = false;
842
843 /*
844 * The code below scribbles on qualname_str in some cases, so we should
845 * reconvert qualname if we need to show the original string in error
846 * messages.
847 */
849
850 /* skip leading whitespace */
851 while (scanner_isspace(*nextp))
852 nextp++;
853
854 for (;;)
855 {
856 char *curname;
857 bool missing_ident = true;
858
859 if (*nextp == '"')
860 {
861 char *endp;
862
863 curname = nextp + 1;
864 for (;;)
865 {
866 endp = strchr(nextp + 1, '"');
867 if (endp == NULL)
870 errmsg("string is not a valid identifier: \"%s\"",
872 errdetail("String has unclosed double quotes.")));
873 if (endp[1] != '"')
874 break;
875 memmove(endp, endp + 1, strlen(endp));
876 nextp = endp;
877 }
878 nextp = endp + 1;
879 *endp = '\0';
880
881 if (endp - curname == 0)
884 errmsg("string is not a valid identifier: \"%s\"",
886 errdetail("Quoted identifier must not be empty.")));
887
890 missing_ident = false;
891 }
892 else if (is_ident_start((unsigned char) *nextp))
893 {
894 char *downname;
895 int len;
896 text *part;
897
898 curname = nextp++;
899 while (is_ident_cont((unsigned char) *nextp))
900 nextp++;
901
902 len = nextp - curname;
903
904 /*
905 * We don't implicitly truncate identifiers. This is useful for
906 * allowing the user to check for specific parts of the identifier
907 * being too long. It's easy enough for the user to get the
908 * truncated names by casting our output to name[].
909 */
910 downname = downcase_identifier(curname, len, false, false);
912 astate = accumArrayResult(astate, PointerGetDatum(part), false,
914 missing_ident = false;
915 }
916
917 if (missing_ident)
918 {
919 /* Different error messages based on where we failed. */
920 if (*nextp == '.')
923 errmsg("string is not a valid identifier: \"%s\"",
925 errdetail("No valid identifier before \".\".")));
926 else if (after_dot)
929 errmsg("string is not a valid identifier: \"%s\"",
931 errdetail("No valid identifier after \".\".")));
932 else
935 errmsg("string is not a valid identifier: \"%s\"",
937 }
938
939 while (scanner_isspace(*nextp))
940 nextp++;
941
942 if (*nextp == '.')
943 {
944 after_dot = true;
945 nextp++;
946 while (scanner_isspace(*nextp))
947 nextp++;
948 }
949 else if (*nextp == '\0')
950 {
951 break;
952 }
953 else
954 {
955 if (strict)
958 errmsg("string is not a valid identifier: \"%s\"",
960 break;
961 }
962 }
963
965}
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
static bool is_ident_cont(unsigned char c)
Definition misc.c:819
#define CStringGetTextDatum(s)
Definition builtins.h:98
int errcode(int sqlerrcode)
Definition elog.c:874
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:151
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
static char * errmsg
const void size_t len
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static int fb(int x)
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition scansup.c:47
bool scanner_isspace(char ch)
Definition scansup.c:105
Definition c.h:776
text * cstring_to_text_with_len(const char *s, int len)
Definition varlena.c:196
char * text_to_cstring(const text *t)
Definition varlena.c:217

References accumArrayResult(), cstring_to_text_with_len(), CStringGetTextDatum, CurrentMemoryContext, downcase_identifier(), ereport, errcode(), errdetail(), errmsg, ERROR, fb(), 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 556 of file misc.c.

557{
558 Oid typid = PG_GETARG_OID(0);
559
560 /*
561 * We loop to find the bottom base type in a stack of domains.
562 */
563 for (;;)
564 {
567
569 if (!HeapTupleIsValid(tup))
570 PG_RETURN_NULL(); /* return NULL for bogus OID */
572 if (typTup->typtype != TYPTYPE_DOMAIN)
573 {
574 /* Not a domain, so done */
576 break;
577 }
578
579 typid = typTup->typbasetype;
581 }
582
583 PG_RETURN_OID(typid);
584}
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_OID(x)
Definition fmgr.h:361
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
unsigned int Oid
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221

References fb(), Form_pg_type, 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 592 of file misc.c.

593{
594 Oid typeid;
595 Oid collid;
596
597 typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
598 if (!typeid)
600 if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
603 errmsg("collations are not supported by type %s",
604 format_type_be(typeid))));
605
607 if (!collid)
610}
Oid collid
#define PG_GET_COLLATION()
Definition fmgr.h:198
char * format_type_be(Oid type_oid)
bool type_is_collatable(Oid typid)
Definition lsyscache.c:3303
char * generate_collation_name(Oid collid)

References collid, cstring_to_text(), ereport, errcode(), errmsg, ERROR, fb(), 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 638 of file misc.c.

639{
640 Oid reloid = PG_GETARG_OID(0);
644 int events;
645
646 /* System columns are never updatable */
647 if (attnum <= 0)
648 PG_RETURN_BOOL(false);
649
652
653 /* We require both updatability and deletability of the relation */
654#define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
655
656 PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
657}
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:360
#define PG_GETARG_INT16(n)
Definition fmgr.h:271
int16 attnum
#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(), fb(), 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 973 of file misc.c.

974{
975 FILE *fd;
976 char lbuffer[MAXPGPATH];
977 char *logfmt;
978
979 /* The log format parameter is optional */
980 if (PG_NARGS() == 0 || PG_ARGISNULL(0))
981 logfmt = NULL;
982 else
983 {
985
986 if (strcmp(logfmt, "stderr") != 0 &&
987 strcmp(logfmt, "csvlog") != 0 &&
988 strcmp(logfmt, "jsonlog") != 0)
991 errmsg("log format \"%s\" is not supported", logfmt),
992 errhint("The supported log formats are \"stderr\", \"csvlog\", and \"jsonlog\".")));
993 }
994
996 if (fd == NULL)
997 {
998 if (errno != ENOENT)
1001 errmsg("could not read file \"%s\": %m",
1004 }
1005
1006#ifdef WIN32
1007 /* syslogger.c writes CRLF line endings on Windows */
1009#endif
1010
1011 /*
1012 * Read the file to gather current log filename(s) registered by the
1013 * syslogger.
1014 */
1015 while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
1016 {
1017 char *log_format;
1018 char *log_filepath;
1019 char *nlpos;
1020
1021 /* Extract log format and log file path from the line. */
1023 log_filepath = strchr(lbuffer, ' ');
1024 if (log_filepath == NULL)
1025 {
1026 /* Uh oh. No space found, so file content is corrupted. */
1027 elog(ERROR,
1028 "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
1029 break;
1030 }
1031
1032 *log_filepath = '\0';
1033 log_filepath++;
1034 nlpos = strchr(log_filepath, '\n');
1035 if (nlpos == NULL)
1036 {
1037 /* Uh oh. No newline found, so file content is corrupted. */
1038 elog(ERROR,
1039 "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
1040 break;
1041 }
1042 *nlpos = '\0';
1043
1044 if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
1045 {
1046 FreeFile(fd);
1048 }
1049 }
1050
1051 /* Close the current log filename file. */
1052 FreeFile(fd);
1053
1055}
int errcode_for_file_access(void)
Definition elog.c:897
int errhint(const char *fmt,...) pg_attribute_printf(1
#define elog(elevel,...)
Definition elog.h:227
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
#define MAXPGPATH
static int fd(const char *x, int i)
#define LOG_METAINFO_DATAFILE
Definition syslogger.h:102

References AllocateFile(), cstring_to_text(), elog, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg, ERROR, fb(), 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 1065 of file misc.c.

1066{
1067 return pg_current_logfile(fcinfo);
1068}
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition misc.c:973

References pg_current_logfile().

◆ pg_error_on_null()

Datum pg_error_on_null ( PG_FUNCTION_ARGS  )

Definition at line 196 of file misc.c.

197{
198 if (PG_ARGISNULL(0))
201 errmsg("null value not allowed")));
202
204}

References ereport, errcode(), errmsg, ERROR, fb(), PG_ARGISNULL, PG_GETARG_DATUM, and PG_RETURN_DATUM.

◆ pg_get_catalog_foreign_keys()

Datum pg_get_catalog_foreign_keys ( PG_FUNCTION_ARGS  )

Definition at line 469 of file misc.c.

470{
473
474 if (SRF_IS_FIRSTCALL())
475 {
476 MemoryContext oldcontext;
477 TupleDesc tupdesc;
478
480 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
481
482 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
483 elog(ERROR, "return type must be a row type");
484 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
485
486 /*
487 * We use array_in to convert the C strings in sys_fk_relationships[]
488 * to text arrays. But we cannot use DirectFunctionCallN to call
489 * array_in, and it wouldn't be very efficient if we could. Fill an
490 * FmgrInfo to use for the call.
491 */
494 funcctx->user_fctx = arrayinp;
495
496 MemoryContextSwitchTo(oldcontext);
497 }
498
500 arrayinp = (FmgrInfo *) funcctx->user_fctx;
501
502 if (funcctx->call_cntr < lengthof(sys_fk_relationships))
503 {
505 Datum values[6];
506 bool nulls[6];
507 HeapTuple tuple;
508
509 memset(nulls, false, sizeof(nulls));
510
511 values[0] = ObjectIdGetDatum(fkrel->fk_table);
513 CStringGetDatum(fkrel->fk_columns),
515 Int32GetDatum(-1));
516 values[2] = ObjectIdGetDatum(fkrel->pk_table);
518 CStringGetDatum(fkrel->pk_columns),
520 Int32GetDatum(-1));
521 values[4] = BoolGetDatum(fkrel->is_array);
522 values[5] = BoolGetDatum(fkrel->is_opt);
523
524 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
525
527 }
528
530}
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define lengthof(array)
Definition c.h:873
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define palloc_object(type)
Definition fe_memutils.h:74
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
#define FunctionCall3(flinfo, arg1, arg2, arg3)
Definition fmgr.h:706
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:1025
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:370
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212

References BlessTupleDesc(), BoolGetDatum(), CStringGetDatum(), elog, ERROR, fb(), fmgr_info(), FunctionCall3, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum(), Int32GetDatum(), lengthof, MemoryContextSwitchTo(), ObjectIdGetDatum(), palloc_object, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, TYPEFUNC_COMPOSITE, and values.

◆ pg_get_keywords()

Datum pg_get_keywords ( PG_FUNCTION_ARGS  )

Definition at line 391 of file misc.c.

392{
394
395 if (SRF_IS_FIRSTCALL())
396 {
397 MemoryContext oldcontext;
398 TupleDesc tupdesc;
399
401 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
402
403 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
404 elog(ERROR, "return type must be a row type");
405 funcctx->tuple_desc = tupdesc;
406 funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
407
408 MemoryContextSwitchTo(oldcontext);
409 }
410
412
413 if (funcctx->call_cntr < ScanKeywords.num_keywords)
414 {
415 char *values[5];
416 HeapTuple tuple;
417
418 /* cast-away-const is ugly but alternatives aren't much better */
419 values[0] = unconstify(char *,
420 GetScanKeyword(funcctx->call_cntr,
421 &ScanKeywords));
422
423 switch (ScanKeywordCategories[funcctx->call_cntr])
424 {
426 values[1] = "U";
427 values[3] = _("unreserved");
428 break;
429 case COL_NAME_KEYWORD:
430 values[1] = "C";
431 values[3] = _("unreserved (cannot be function or type name)");
432 break;
434 values[1] = "T";
435 values[3] = _("reserved (can be function or type name)");
436 break;
437 case RESERVED_KEYWORD:
438 values[1] = "R";
439 values[3] = _("reserved");
440 break;
441 default: /* shouldn't be possible */
442 values[1] = NULL;
443 values[3] = NULL;
444 break;
445 }
446
447 if (ScanKeywordBareLabel[funcctx->call_cntr])
448 {
449 values[2] = "true";
450 values[4] = _("can be bare label");
451 }
452 else
453 {
454 values[2] = "false";
455 values[4] = _("requires AS");
456 }
457
458 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
459
461 }
462
464}
#define unconstify(underlying_type, expr)
Definition c.h:1325
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:95
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
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

References _, BuildTupleFromCStrings(), COL_NAME_KEYWORD, elog, ERROR, fb(), get_call_result_type(), GetScanKeyword(), HeapTupleGetDatum(), MemoryContextSwitchTo(), ScanKeywordList::num_keywords, RESERVED_KEYWORD, ScanKeywordBareLabel, ScanKeywordCategories, ScanKeywords, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, 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 1074 of file misc.c.

1075{
1076 Oid reloid = PG_GETARG_OID(0);
1077 Oid idxoid;
1078 Relation rel;
1079
1080 rel = table_open(reloid, AccessShareLock);
1083
1084 if (OidIsValid(idxoid))
1086 else
1088}
#define AccessShareLock
Definition lockdefs.h:36
Oid RelationGetReplicaIndex(Relation relation)
Definition relcache.c:5063
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References AccessShareLock, fb(), 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 689 of file misc.c.

690{
694 TupleDesc tupdesc;
695 Datum values[4];
696 bool isnull[4];
697
698 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
699 elog(ERROR, "return type must be a row type");
700
701 /* Enable details_wanted */
702 escontext.details_wanted = true;
703
705 &escontext))
706 memset(isnull, true, sizeof(isnull));
707 else
708 {
709 char *sqlstate;
710
711 Assert(escontext.error_occurred);
712 Assert(escontext.error_data != NULL);
713 Assert(escontext.error_data->message != NULL);
714
715 memset(isnull, false, sizeof(isnull));
716
718
719 if (escontext.error_data->detail != NULL)
721 else
722 isnull[1] = true;
723
724 if (escontext.error_data->hint != NULL)
725 values[2] = CStringGetTextDatum(escontext.error_data->hint);
726 else
727 isnull[2] = true;
728
729 sqlstate = unpack_sql_state(escontext.error_data->sqlerrcode);
730 values[3] = CStringGetTextDatum(sqlstate);
731 }
732
733 return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
734}
static bool pg_input_is_valid_common(FunctionCallInfo fcinfo, text *txt, text *typname, ErrorSaveContext *escontext)
Definition misc.c:738
char * unpack_sql_state(int sql_state)
Definition elog.c:3654
NameData typname
Definition pg_type.h:43
int sqlerrcode
Definition elog.h:432
char * detail
Definition elog.h:434
char * message
Definition elog.h:433
char * hint
Definition elog.h:436
ErrorData * error_data
Definition miscnodes.h:49

References Assert, CStringGetTextDatum, ErrorData::detail, ErrorSaveContext::details_wanted, elog, ERROR, ErrorSaveContext::error_data, ErrorSaveContext::error_occurred, fb(), 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 669 of file misc.c.

670{
674
676 &escontext));
677}

References fb(), 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 738 of file misc.c.

741{
742 char *str = text_to_cstring(txt);
745
746 /*
747 * We arrange to look up the needed I/O info just once per series of
748 * calls, assuming the data type doesn't change underneath us.
749 */
750 my_extra = (ValidIOData *) fcinfo->flinfo->fn_extra;
751 if (my_extra == NULL)
752 {
753 fcinfo->flinfo->fn_extra =
755 sizeof(ValidIOData));
756 my_extra = (ValidIOData *) fcinfo->flinfo->fn_extra;
757 my_extra->typoid = InvalidOid;
758 /* Detect whether typname argument is constant. */
759 my_extra->typname_constant = get_fn_expr_arg_stable(fcinfo->flinfo, 1);
760 }
761
762 /*
763 * If the typname argument is constant, we only need to parse it the first
764 * time through.
765 */
766 if (my_extra->typoid == InvalidOid || !my_extra->typname_constant)
767 {
769 Oid typoid;
770
771 /* Parse type-name argument to obtain type OID and encoded typmod. */
772 (void) parseTypeString(typnamestr, &typoid, &my_extra->typmod, NULL);
773
774 /* Update type-specific info if typoid changed. */
775 if (my_extra->typoid != typoid)
776 {
777 getTypeInputInfo(typoid,
778 &my_extra->typiofunc,
779 &my_extra->typioparam);
780 fmgr_info_cxt(my_extra->typiofunc, &my_extra->inputproc,
781 fcinfo->flinfo->fn_mcxt);
782 my_extra->typoid = typoid;
783 }
784 }
785
786 /* Now we can try to perform the conversion. */
787 return InputFunctionCallSafe(&my_extra->inputproc,
788 str,
789 my_extra->typioparam,
790 my_extra->typmod,
791 (Node *) escontext,
792 &converted);
793}
bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1941
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition fmgr.c:139
bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
Definition fmgr.c:1586
const char * str
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition lsyscache.c:3096
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
bool parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, Node *escontext)
Definition parse_type.c:785
#define InvalidOid
void * fn_extra
Definition fmgr.h:64
MemoryContext fn_mcxt
Definition fmgr.h:65
Definition nodes.h:135

References fb(), FunctionCallInfoBaseData::flinfo, fmgr_info_cxt(), FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, get_fn_expr_arg_stable(), getTypeInputInfo(), InputFunctionCallSafe(), InvalidOid, MemoryContextAlloc(), parseTypeString(), str, text_to_cstring(), and typname.

Referenced by pg_input_error_info(), and pg_input_is_valid().

◆ pg_num_nonnulls()

Datum pg_num_nonnulls ( PG_FUNCTION_ARGS  )

Definition at line 180 of file misc.c.

181{
182 int32 nargs,
183 nulls;
184
185 if (!count_nulls(fcinfo, &nargs, &nulls))
187
188 PG_RETURN_INT32(nargs - nulls);
189}
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition misc.c:78
#define PG_RETURN_INT32(x)
Definition fmgr.h:355

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

◆ pg_num_nulls()

Datum pg_num_nulls ( PG_FUNCTION_ARGS  )

Definition at line 164 of file misc.c.

165{
166 int32 nargs,
167 nulls;
168
169 if (!count_nulls(fcinfo, &nargs, &nulls))
171
172 PG_RETURN_INT32(nulls);
173}

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 621 of file misc.c.

622{
623 Oid reloid = PG_GETARG_OID(0);
625
627}

References fb(), 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 332 of file misc.c.

333{
335 int64 usecs;
337
338 /*
339 * Convert the delay to int64 microseconds, rounding up any fraction, and
340 * silently limiting it to PG_INT64_MAX/2 microseconds (about 150K years)
341 * to ensure the computation of endtime won't overflow. Historically
342 * we've treated NaN as "no wait", not an error, so keep that behavior.
343 */
344 if (isnan(secs) || secs <= 0.0)
346 secs *= USECS_PER_SEC; /* we assume overflow will produce +Inf */
347 secs = ceil(secs); /* round up any fractional microsecond */
348 usecs = (int64) Min(secs, (float8) (PG_INT64_MAX / 2));
349
350 /*
351 * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
352 * important signal (such as SIGALRM or SIGINT) arrives. Because
353 * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
354 * might ask for more than that, we sleep for at most 10 minutes and then
355 * loop.
356 *
357 * By computing the intended stop time initially, we avoid accumulation of
358 * extra delay across multiple sleeps. This also ensures we won't delay
359 * less than the specified time when WaitLatch is terminated early by a
360 * non-query-canceling signal such as SIGHUP.
361 */
363
364 for (;;)
365 {
367 long delay_ms;
368
370
372 if (delay >= 600 * USECS_PER_SEC)
373 delay_ms = 600000;
374 else if (delay > 0)
375 delay_ms = (long) ((delay + 999) / 1000);
376 else
377 break;
378
381 delay_ms,
384 }
385
387}
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1639
#define Min(x, y)
Definition c.h:1091
int64_t int64
Definition c.h:621
double float8
Definition c.h:714
#define PG_INT64_MAX
Definition c.h:676
int64 TimestampTz
Definition timestamp.h:39
#define USECS_PER_SEC
Definition timestamp.h:134
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
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:123
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET

References CHECK_FOR_INTERRUPTS, fb(), 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 240 of file misc.c.

241{
242 Oid tablespaceOid = PG_GETARG_OID(0);
243 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
244 char *location;
245 DIR *dirdesc;
246 struct dirent *de;
247
249
250 if (tablespaceOid == GLOBALTABLESPACE_OID)
251 {
253 (errmsg("global tablespace never has databases")));
254 /* return empty tuplestore */
255 return (Datum) 0;
256 }
257
258 if (tablespaceOid == DEFAULTTABLESPACE_OID)
259 location = "base";
260 else
261 location = psprintf("%s/%u/%s", PG_TBLSPC_DIR, tablespaceOid,
263
264 dirdesc = AllocateDir(location);
265
266 if (!dirdesc)
267 {
268 /* the only expected error is ENOENT */
269 if (errno != ENOENT)
272 errmsg("could not open directory \"%s\": %m",
273 location)));
275 (errmsg("%u is not a tablespace OID", tablespaceOid)));
276 /* return empty tuplestore */
277 return (Datum) 0;
278 }
279
280 while ((de = ReadDir(dirdesc, location)) != NULL)
281 {
282 Oid datOid = atooid(de->d_name);
283 char *subdir;
284 bool isempty;
285 Datum values[1];
286 bool nulls[1];
287
288 /* this test skips . and .., but is awfully weak */
289 if (!datOid)
290 continue;
291
292 /* if database subdir is empty, don't report tablespace as used */
293
294 subdir = psprintf("%s/%s", location, de->d_name);
296 pfree(subdir);
297
298 if (isempty)
299 continue; /* indeed, nothing in it */
300
302 nulls[0] = false;
303
304 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
305 values, nulls);
306 }
307
308 FreeDir(dirdesc);
309 return (Datum) 0;
310}
bool directory_is_empty(const char *path)
Definition tablespace.c:861
#define WARNING
Definition elog.h:36
int FreeDir(DIR *dir)
Definition fd.c:3009
DIR * AllocateDir(const char *dirname)
Definition fd.c:2891
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition fd.c:2957
void InitMaterializedSRF(FunctionCallInfo fcinfo, uint32 flags)
Definition funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition funcapi.h:296
void pfree(void *pointer)
Definition mcxt.c:1616
#define atooid(x)
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
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785

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

◆ pg_tablespace_location()

Datum pg_tablespace_location ( PG_FUNCTION_ARGS  )

Definition at line 317 of file misc.c.

318{
319 Oid tablespaceOid = PG_GETARG_OID(0);
320 char *tablespaceLoc;
321
322 /* Get LOCATION string from its OID */
323 tablespaceLoc = get_tablespace_location(tablespaceOid);
324
326}
char * get_tablespace_location(Oid tablespaceOid)

References cstring_to_text(), fb(), get_tablespace_location(), PG_GETARG_OID, and PG_RETURN_TEXT_P.

◆ pg_typeof()

Datum pg_typeof ( PG_FUNCTION_ARGS  )

Definition at line 537 of file misc.c.

538{
539 PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
540}

References get_fn_expr_argtype(), and PG_RETURN_OID.