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

Go to the source code of this file.

Macros

#define GetNowFloat()   ((float8) GetCurrentTimestamp() / 1000000.0)
 
#define REQ_EVENTS   ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
 

Functions

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_typeof (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)
 
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)
 

Macro Definition Documentation

◆ GetNowFloat

#define GetNowFloat ( )    ((float8) GetCurrentTimestamp() / 1000000.0)

Referenced by pg_sleep().

◆ REQ_EVENTS

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

Referenced by pg_column_is_updatable().

Function Documentation

◆ count_nulls()

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

Definition at line 50 of file misc.c.

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

Referenced by pg_num_nonnulls(), and pg_num_nulls().

52 {
53  int32 count = 0;
54  int i;
55 
56  /* Did we get a VARIADIC array argument, or separate arguments? */
57  if (get_fn_expr_variadic(fcinfo->flinfo))
58  {
59  ArrayType *arr;
60  int ndims,
61  nitems,
62  *dims;
63  bits8 *bitmap;
64 
65  Assert(PG_NARGS() == 1);
66 
67  /*
68  * If we get a null as VARIADIC array argument, we can't say anything
69  * useful about the number of elements, so return NULL. This behavior
70  * is consistent with other variadic functions - see concat_internal.
71  */
72  if (PG_ARGISNULL(0))
73  return false;
74 
75  /*
76  * Non-null argument had better be an array. We assume that any call
77  * context that could let get_fn_expr_variadic return true will have
78  * checked that a VARIADIC-labeled parameter actually is an array. So
79  * it should be okay to just Assert that it's an array rather than
80  * doing a full-fledged error check.
81  */
83 
84  /* OK, safe to fetch the array value */
85  arr = PG_GETARG_ARRAYTYPE_P(0);
86 
87  /* Count the array elements */
88  ndims = ARR_NDIM(arr);
89  dims = ARR_DIMS(arr);
90  nitems = ArrayGetNItems(ndims, dims);
91 
92  /* Count those that are NULL */
93  bitmap = ARR_NULLBITMAP(arr);
94  if (bitmap)
95  {
96  int bitmask = 1;
97 
98  for (i = 0; i < nitems; i++)
99  {
100  if ((*bitmap & bitmask) == 0)
101  count++;
102 
103  bitmask <<= 1;
104  if (bitmask == 0x100)
105  {
106  bitmap++;
107  bitmask = 1;
108  }
109  }
110  }
111 
112  *nargs = nitems;
113  *nulls = count;
114  }
115  else
116  {
117  /* Separate arguments, so just count 'em */
118  for (i = 0; i < PG_NARGS(); i++)
119  {
120  if (PG_ARGISNULL(i))
121  count++;
122  }
123 
124  *nargs = PG_NARGS();
125  *nulls = count;
126  }
127 
128  return true;
129 }
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1938
#define OidIsValid(objectId)
Definition: c.h:644
signed int int32
Definition: c.h:355
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1804
#define ARR_DIMS(a)
Definition: array.h:282
uint8 bits8
Definition: c.h:374
FmgrInfo * flinfo
Definition: fmgr.h:87
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:738
#define PG_NARGS()
Definition: fmgr.h:203
#define ARR_NDIM(a)
Definition: array.h:278
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2660
int i
#define ARR_NULLBITMAP(a)
Definition: array.h:288

◆ current_database()

Datum current_database ( PG_FUNCTION_ARGS  )

Definition at line 169 of file misc.c.

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

Referenced by ExecEvalSQLValueFunction().

170 {
171  Name db;
172 
173  db = (Name) palloc(NAMEDATALEN);
174 
176  PG_RETURN_NAME(db);
177 }
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define NAMEDATALEN
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
Definition: c.h:609
Oid MyDatabaseId
Definition: globals.c:85
void * palloc(Size size)
Definition: mcxt.c:949
NameData * Name
Definition: c.h:613
#define PG_RETURN_NAME(x)
Definition: fmgr.h:362

◆ current_query()

Datum current_query ( PG_FUNCTION_ARGS  )

Definition at line 186 of file misc.c.

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

Referenced by dblink_current_query().

187 {
188  /* there is no easy way to access the more concise 'query_string' */
189  if (debug_query_string)
191  else
192  PG_RETURN_NULL();
193 }
const char * debug_query_string
Definition: postgres.c:88
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
text * cstring_to_text(const char *s)
Definition: varlena.c:172
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ is_ident_cont()

static bool is_ident_cont ( unsigned char  c)
static

Definition at line 582 of file misc.c.

References is_ident_start().

Referenced by parse_ident().

583 {
584  /* Can be digit or dollar sign ... */
585  if ((c >= '0' && c <= '9') || c == '$')
586  return true;
587  /* ... or an identifier start character */
588  return is_ident_start(c);
589 }
static bool is_ident_start(unsigned char c)
Definition: misc.c:564
char * c

◆ is_ident_start()

static bool is_ident_start ( unsigned char  c)
static

Definition at line 564 of file misc.c.

References IS_HIGHBIT_SET.

Referenced by is_ident_cont(), and parse_ident().

565 {
566  /* Underscores and ASCII letters are OK */
567  if (c == '_')
568  return true;
569  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
570  return true;
571  /* Any high-bit-set character is OK (might be part of a multibyte char) */
572  if (IS_HIGHBIT_SET(c))
573  return true;
574  return false;
575 }
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1119
char * c

◆ parse_ident()

Datum parse_ident ( PG_FUNCTION_ARGS  )

Definition at line 597 of file misc.c.

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

598 {
599  text *qualname = PG_GETARG_TEXT_PP(0);
600  bool strict = PG_GETARG_BOOL(1);
601  char *qualname_str = text_to_cstring(qualname);
602  ArrayBuildState *astate = NULL;
603  char *nextp;
604  bool after_dot = false;
605 
606  /*
607  * The code below scribbles on qualname_str in some cases, so we should
608  * reconvert qualname if we need to show the original string in error
609  * messages.
610  */
611  nextp = qualname_str;
612 
613  /* skip leading whitespace */
614  while (scanner_isspace(*nextp))
615  nextp++;
616 
617  for (;;)
618  {
619  char *curname;
620  bool missing_ident = true;
621 
622  if (*nextp == '"')
623  {
624  char *endp;
625 
626  curname = nextp + 1;
627  for (;;)
628  {
629  endp = strchr(nextp + 1, '"');
630  if (endp == NULL)
631  ereport(ERROR,
632  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
633  errmsg("string is not a valid identifier: \"%s\"",
634  text_to_cstring(qualname)),
635  errdetail("String has unclosed double quotes.")));
636  if (endp[1] != '"')
637  break;
638  memmove(endp, endp + 1, strlen(endp));
639  nextp = endp;
640  }
641  nextp = endp + 1;
642  *endp = '\0';
643 
644  if (endp - curname == 0)
645  ereport(ERROR,
646  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
647  errmsg("string is not a valid identifier: \"%s\"",
648  text_to_cstring(qualname)),
649  errdetail("Quoted identifier must not be empty.")));
650 
651  astate = accumArrayResult(astate, CStringGetTextDatum(curname),
652  false, TEXTOID, CurrentMemoryContext);
653  missing_ident = false;
654  }
655  else if (is_ident_start((unsigned char) *nextp))
656  {
657  char *downname;
658  int len;
659  text *part;
660 
661  curname = nextp++;
662  while (is_ident_cont((unsigned char) *nextp))
663  nextp++;
664 
665  len = nextp - curname;
666 
667  /*
668  * We don't implicitly truncate identifiers. This is useful for
669  * allowing the user to check for specific parts of the identifier
670  * being too long. It's easy enough for the user to get the
671  * truncated names by casting our output to name[].
672  */
673  downname = downcase_identifier(curname, len, false, false);
674  part = cstring_to_text_with_len(downname, len);
675  astate = accumArrayResult(astate, PointerGetDatum(part), false,
676  TEXTOID, CurrentMemoryContext);
677  missing_ident = false;
678  }
679 
680  if (missing_ident)
681  {
682  /* Different error messages based on where we failed. */
683  if (*nextp == '.')
684  ereport(ERROR,
685  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
686  errmsg("string is not a valid identifier: \"%s\"",
687  text_to_cstring(qualname)),
688  errdetail("No valid identifier before \".\".")));
689  else if (after_dot)
690  ereport(ERROR,
691  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
692  errmsg("string is not a valid identifier: \"%s\"",
693  text_to_cstring(qualname)),
694  errdetail("No valid identifier after \".\".")));
695  else
696  ereport(ERROR,
697  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
698  errmsg("string is not a valid identifier: \"%s\"",
699  text_to_cstring(qualname))));
700  }
701 
702  while (scanner_isspace(*nextp))
703  nextp++;
704 
705  if (*nextp == '.')
706  {
707  after_dot = true;
708  nextp++;
709  while (scanner_isspace(*nextp))
710  nextp++;
711  }
712  else if (*nextp == '\0')
713  {
714  break;
715  }
716  else
717  {
718  if (strict)
719  ereport(ERROR,
720  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
721  errmsg("string is not a valid identifier: \"%s\"",
722  text_to_cstring(qualname))));
723  break;
724  }
725  }
726 
728 }
static bool is_ident_start(unsigned char c)
Definition: misc.c:564
#define PointerGetDatum(X)
Definition: postgres.h:556
int errcode(int sqlerrcode)
Definition: elog.c:610
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#define ERROR
Definition: elog.h:43
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
int errdetail(const char *fmt,...)
Definition: elog.c:957
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5123
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:352
bool scanner_isspace(char ch)
Definition: scansup.c:220
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition: scansup.c:139
#define ereport(elevel,...)
Definition: elog.h:144
static bool is_ident_cont(unsigned char c)
Definition: misc.c:582
char * text_to_cstring(const text *t)
Definition: varlena.c:205
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5059
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define CStringGetTextDatum(s)
Definition: builtins.h:87
Definition: c.h:555

◆ pg_collation_for()

Datum pg_collation_for ( PG_FUNCTION_ARGS  )

Definition at line 491 of file misc.c.

References 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().

492 {
493  Oid typeid;
494  Oid collid;
495 
496  typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
497  if (!typeid)
498  PG_RETURN_NULL();
499  if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
500  ereport(ERROR,
501  (errcode(ERRCODE_DATATYPE_MISMATCH),
502  errmsg("collations are not supported by type %s",
503  format_type_be(typeid))));
504 
505  collid = PG_GET_COLLATION();
506  if (!collid)
507  PG_RETURN_NULL();
509 }
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:327
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
char * generate_collation_name(Oid collid)
Definition: ruleutils.c:11253
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1804
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
text * cstring_to_text(const char *s)
Definition: varlena.c:172
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2909
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_column_is_updatable()

Datum pg_column_is_updatable ( PG_FUNCTION_ARGS  )

Definition at line 537 of file misc.c.

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.

538 {
539  Oid reloid = PG_GETARG_OID(0);
542  bool include_triggers = PG_GETARG_BOOL(2);
543  int events;
544 
545  /* System columns are never updatable */
546  if (attnum <= 0)
547  PG_RETURN_BOOL(false);
548 
549  events = relation_is_updatable(reloid, NIL, include_triggers,
550  bms_make_singleton(col));
551 
552  /* We require both updatability and deletability of the relation */
553 #define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
554 
555  PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
556 }
#define NIL
Definition: pg_list.h:65
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
unsigned int Oid
Definition: postgres_ext.h:31
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:186
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
int relation_is_updatable(Oid reloid, List *outer_reloids, bool include_triggers, Bitmapset *include_cols)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_GETARG_INT16(n)
Definition: fmgr.h:271
#define REQ_EVENTS
int16 attnum
Definition: pg_attribute.h:79
int16 AttrNumber
Definition: attnum.h:21

◆ pg_current_logfile()

Datum pg_current_logfile ( PG_FUNCTION_ARGS  )

Definition at line 736 of file misc.c.

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().

737 {
738  FILE *fd;
739  char lbuffer[MAXPGPATH];
740  char *logfmt;
741  char *log_filepath;
742  char *log_format = lbuffer;
743  char *nlpos;
744 
745  /* The log format parameter is optional */
746  if (PG_NARGS() == 0 || PG_ARGISNULL(0))
747  logfmt = NULL;
748  else
749  {
750  logfmt = text_to_cstring(PG_GETARG_TEXT_PP(0));
751 
752  if (strcmp(logfmt, "stderr") != 0 && strcmp(logfmt, "csvlog") != 0)
753  ereport(ERROR,
754  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
755  errmsg("log format \"%s\" is not supported", logfmt),
756  errhint("The supported log formats are \"stderr\" and \"csvlog\".")));
757  }
758 
760  if (fd == NULL)
761  {
762  if (errno != ENOENT)
763  ereport(ERROR,
765  errmsg("could not read file \"%s\": %m",
767  PG_RETURN_NULL();
768  }
769 
770  /*
771  * Read the file to gather current log filename(s) registered by the
772  * syslogger.
773  */
774  while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
775  {
776  /*
777  * Extract log format and log file path from the line; lbuffer ==
778  * log_format, they share storage.
779  */
780  log_filepath = strchr(lbuffer, ' ');
781  if (log_filepath == NULL)
782  {
783  /* Uh oh. No space found, so file content is corrupted. */
784  elog(ERROR,
785  "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
786  break;
787  }
788 
789  *log_filepath = '\0';
790  log_filepath++;
791  nlpos = strchr(log_filepath, '\n');
792  if (nlpos == NULL)
793  {
794  /* Uh oh. No newline found, so file content is corrupted. */
795  elog(ERROR,
796  "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
797  break;
798  }
799  *nlpos = '\0';
800 
801  if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
802  {
803  FreeFile(fd);
804  PG_RETURN_TEXT_P(cstring_to_text(log_filepath));
805  }
806  }
807 
808  /* Close the current log filename file. */
809  FreeFile(fd);
810 
811  PG_RETURN_NULL();
812 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG_METAINFO_DATAFILE
Definition: syslogger.h:95
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2320
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
text * cstring_to_text(const char *s)
Definition: varlena.c:172
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_NARGS()
Definition: fmgr.h:203
int FreeFile(FILE *file)
Definition: fd.c:2519
char * text_to_cstring(const text *t)
Definition: varlena.c:205
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_current_logfile_1arg()

Datum pg_current_logfile_1arg ( PG_FUNCTION_ARGS  )

Definition at line 822 of file misc.c.

References pg_current_logfile().

823 {
824  return pg_current_logfile(fcinfo);
825 }
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition: misc.c:736

◆ pg_get_keywords()

Datum pg_get_keywords ( PG_FUNCTION_ARGS  )

Definition at line 406 of file misc.c.

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

407 {
408  FuncCallContext *funcctx;
409 
410  if (SRF_IS_FIRSTCALL())
411  {
412  MemoryContext oldcontext;
413  TupleDesc tupdesc;
414 
415  funcctx = SRF_FIRSTCALL_INIT();
416  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
417 
418  tupdesc = CreateTemplateTupleDesc(3);
419  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
420  TEXTOID, -1, 0);
421  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
422  CHAROID, -1, 0);
423  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc",
424  TEXTOID, -1, 0);
425 
426  funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
427 
428  MemoryContextSwitchTo(oldcontext);
429  }
430 
431  funcctx = SRF_PERCALL_SETUP();
432 
433  if (funcctx->call_cntr < ScanKeywords.num_keywords)
434  {
435  char *values[3];
436  HeapTuple tuple;
437 
438  /* cast-away-const is ugly but alternatives aren't much better */
439  values[0] = unconstify(char *,
440  GetScanKeyword(funcctx->call_cntr,
441  &ScanKeywords));
442 
443  switch (ScanKeywordCategories[funcctx->call_cntr])
444  {
445  case UNRESERVED_KEYWORD:
446  values[1] = "U";
447  values[2] = _("unreserved");
448  break;
449  case COL_NAME_KEYWORD:
450  values[1] = "C";
451  values[2] = _("unreserved (cannot be function or type name)");
452  break;
454  values[1] = "T";
455  values[2] = _("reserved (can be function or type name)");
456  break;
457  case RESERVED_KEYWORD:
458  values[1] = "R";
459  values[2] = _("reserved");
460  break;
461  default: /* shouldn't be possible */
462  values[1] = NULL;
463  values[2] = NULL;
464  break;
465  }
466 
467  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
468 
469  SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
470  }
471 
472  SRF_RETURN_DONE(funcctx);
473 }
uint64 call_cntr
Definition: funcapi.h:65
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:293
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:29
#define UNRESERVED_KEYWORD
Definition: keywords.h:20
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:297
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition: kwlookup.h:39
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:2116
PGDLLIMPORT const ScanKeywordList ScanKeywords
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
#define TYPE_FUNC_NAME_KEYWORD
Definition: keywords.h:22
AttInMetadata * attinmeta
Definition: funcapi.h:91
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
#define unconstify(underlying_type, expr)
Definition: c.h:1206
int num_keywords
Definition: kwlookup.h:30
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2067
#define RESERVED_KEYWORD
Definition: keywords.h:23
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
#define COL_NAME_KEYWORD
Definition: keywords.h:21
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int16 AttrNumber
Definition: attnum.h:21
#define _(x)
Definition: elog.c:88
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:317
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295

◆ pg_get_replica_identity_index()

Datum pg_get_replica_identity_index ( PG_FUNCTION_ARGS  )

Definition at line 831 of file misc.c.

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

832 {
833  Oid reloid = PG_GETARG_OID(0);
834  Oid idxoid;
835  Relation rel;
836 
837  rel = table_open(reloid, AccessShareLock);
838  idxoid = RelationGetReplicaIndex(rel);
840 
841  if (OidIsValid(idxoid))
842  PG_RETURN_OID(idxoid);
843  else
844  PG_RETURN_NULL();
845 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4715
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define PG_RETURN_OID(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_num_nonnulls()

Datum pg_num_nonnulls ( PG_FUNCTION_ARGS  )

Definition at line 152 of file misc.c.

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

153 {
154  int32 nargs,
155  nulls;
156 
157  if (!count_nulls(fcinfo, &nargs, &nulls))
158  PG_RETURN_NULL();
159 
160  PG_RETURN_INT32(nargs - nulls);
161 }
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition: misc.c:50
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
signed int int32
Definition: c.h:355
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_num_nulls()

Datum pg_num_nulls ( PG_FUNCTION_ARGS  )

Definition at line 136 of file misc.c.

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

137 {
138  int32 nargs,
139  nulls;
140 
141  if (!count_nulls(fcinfo, &nargs, &nulls))
142  PG_RETURN_NULL();
143 
144  PG_RETURN_INT32(nulls);
145 }
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition: misc.c:50
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
signed int int32
Definition: c.h:355
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_relation_is_updatable()

Datum pg_relation_is_updatable ( PG_FUNCTION_ARGS  )

Definition at line 520 of file misc.c.

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

521 {
522  Oid reloid = PG_GETARG_OID(0);
523  bool include_triggers = PG_GETARG_BOOL(1);
524 
525  PG_RETURN_INT32(relation_is_updatable(reloid, NIL, include_triggers, NULL));
526 }
#define NIL
Definition: pg_list.h:65
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
int relation_is_updatable(Oid reloid, List *outer_reloids, bool include_triggers, Bitmapset *include_cols)

◆ pg_sleep()

Datum pg_sleep ( PG_FUNCTION_ARGS  )

Definition at line 358 of file misc.c.

References CHECK_FOR_INTERRUPTS, GetNowFloat, MyLatch, PG_GETARG_FLOAT8, PG_RETURN_VOID, ResetLatch(), WAIT_EVENT_PG_SLEEP, WaitLatch(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_TIMEOUT.

359 {
360  float8 secs = PG_GETARG_FLOAT8(0);
361  float8 endtime;
362 
363  /*
364  * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
365  * important signal (such as SIGALRM or SIGINT) arrives. Because
366  * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
367  * might ask for more than that, we sleep for at most 10 minutes and then
368  * loop.
369  *
370  * By computing the intended stop time initially, we avoid accumulation of
371  * extra delay across multiple sleeps. This also ensures we won't delay
372  * less than the specified time when WaitLatch is terminated early by a
373  * non-query-canceling signal such as SIGHUP.
374  */
375 #define GetNowFloat() ((float8) GetCurrentTimestamp() / 1000000.0)
376 
377  endtime = GetNowFloat() + secs;
378 
379  for (;;)
380  {
381  float8 delay;
382  long delay_ms;
383 
385 
386  delay = endtime - GetNowFloat();
387  if (delay >= 600.0)
388  delay_ms = 600000;
389  else if (delay > 0.0)
390  delay_ms = (long) ceil(delay * 1000.0);
391  else
392  break;
393 
394  (void) WaitLatch(MyLatch,
396  delay_ms,
399  }
400 
401  PG_RETURN_VOID();
402 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:281
#define WL_TIMEOUT
Definition: latch.h:127
void ResetLatch(Latch *latch)
Definition: latch.c:540
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:365
#define GetNowFloat()
double float8
Definition: c.h:491
#define PG_RETURN_VOID()
Definition: fmgr.h:348
struct Latch * MyLatch
Definition: globals.c:54
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
#define WL_LATCH_SET
Definition: latch.h:124
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

◆ pg_tablespace_databases()

Datum pg_tablespace_databases ( PG_FUNCTION_ARGS  )

Definition at line 198 of file misc.c.

References AllocateDir(), ReturnSetInfo::allowedModes, atooid, CreateTemplateTupleDesc(), directory_is_empty(), ReturnSetInfo::econtext, ExprContext::ecxt_per_query_memory, ereport, errcode(), errcode_for_file_access(), errmsg(), ERROR, FreeDir(), IsA, MemoryContextSwitchTo(), ObjectIdGetDatum, pfree(), PG_GETARG_OID, psprintf(), ReadDir(), ReturnSetInfo::returnMode, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, SFRM_Materialize_Random, TABLESPACE_VERSION_DIRECTORY, TupleDescInitEntry(), tuplestore_begin_heap(), tuplestore_putvalues(), values, WARNING, and work_mem.

199 {
200  Oid tablespaceOid = PG_GETARG_OID(0);
201  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
202  bool randomAccess;
203  TupleDesc tupdesc;
204  Tuplestorestate *tupstore;
205  char *location;
206  DIR *dirdesc;
207  struct dirent *de;
208  MemoryContext oldcontext;
209 
210  /* check to see if caller supports us returning a tuplestore */
211  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
212  ereport(ERROR,
213  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
214  errmsg("set-valued function called in context that cannot accept a set")));
215  if (!(rsinfo->allowedModes & SFRM_Materialize))
216  ereport(ERROR,
217  (errcode(ERRCODE_SYNTAX_ERROR),
218  errmsg("materialize mode required, but it is not allowed in this context")));
219 
220  /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
222 
223  tupdesc = CreateTemplateTupleDesc(1);
224  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_tablespace_databases",
225  OIDOID, -1, 0);
226 
227  randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;
228  tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
229 
230  rsinfo->returnMode = SFRM_Materialize;
231  rsinfo->setResult = tupstore;
232  rsinfo->setDesc = tupdesc;
233 
234  MemoryContextSwitchTo(oldcontext);
235 
236  if (tablespaceOid == GLOBALTABLESPACE_OID)
237  {
239  (errmsg("global tablespace never has databases")));
240  /* return empty tuplestore */
241  return (Datum) 0;
242  }
243 
244  if (tablespaceOid == DEFAULTTABLESPACE_OID)
245  location = psprintf("base");
246  else
247  location = psprintf("pg_tblspc/%u/%s", tablespaceOid,
249 
250  dirdesc = AllocateDir(location);
251 
252  if (!dirdesc)
253  {
254  /* the only expected error is ENOENT */
255  if (errno != ENOENT)
256  ereport(ERROR,
258  errmsg("could not open directory \"%s\": %m",
259  location)));
261  (errmsg("%u is not a tablespace OID", tablespaceOid)));
262  /* return empty tuplestore */
263  return (Datum) 0;
264  }
265 
266  while ((de = ReadDir(dirdesc, location)) != NULL)
267  {
268  Oid datOid = atooid(de->d_name);
269  char *subdir;
270  bool isempty;
271  Datum values[1];
272  bool nulls[1];
273 
274  /* this test skips . and .., but is awfully weak */
275  if (!datOid)
276  continue;
277 
278  /* if database subdir is empty, don't report tablespace as used */
279 
280  subdir = psprintf("%s/%s", location, de->d_name);
281  isempty = directory_is_empty(subdir);
282  pfree(subdir);
283 
284  if (isempty)
285  continue; /* indeed, nothing in it */
286 
287  values[0] = ObjectIdGetDatum(datOid);
288  nulls[0] = false;
289 
290  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
291  }
292 
293  FreeDir(dirdesc);
294  return (Datum) 0;
295 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:610
bool directory_is_empty(const char *path)
Definition: tablespace.c:846
unsigned int Oid
Definition: postgres_ext.h:31
Definition: dirent.h:9
void pfree(void *pointer)
Definition: mcxt.c:1056
Definition: dirent.c:25
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
int errcode_for_file_access(void)
Definition: elog.c:633
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
#define atooid(x)
Definition: postgres_ext.h:42
#define WARNING
Definition: elog.h:40
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
uintptr_t Datum
Definition: postgres.h:367
int work_mem
Definition: globals.c:121
#define ereport(elevel,...)
Definition: elog.h:144
int allowedModes
Definition: execnodes.h:305
SetFunctionReturnMode returnMode
Definition: execnodes.h:307
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2647
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:233
Tuplestorestate * setResult
Definition: execnodes.h:310
static Datum values[MAXATTR]
Definition: bootstrap.c:167
ExprContext * econtext
Definition: execnodes.h:303
TupleDesc setDesc
Definition: execnodes.h:311
int errmsg(const char *fmt,...)
Definition: elog.c:824
int16 AttrNumber
Definition: attnum.h:21
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ pg_tablespace_location()

Datum pg_tablespace_location ( PG_FUNCTION_ARGS  )

Definition at line 302 of file misc.c.

References cstring_to_text(), ereport, errcode(), errcode_for_file_access(), errmsg(), ERROR, InvalidOid, MAXPGPATH, MyDatabaseTableSpace, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_TEXT_P, readlink, and snprintf.

303 {
304  Oid tablespaceOid = PG_GETARG_OID(0);
305  char sourcepath[MAXPGPATH];
306  char targetpath[MAXPGPATH];
307  int rllen;
308 
309  /*
310  * It's useful to apply this function to pg_class.reltablespace, wherein
311  * zero means "the database's default tablespace". So, rather than
312  * throwing an error for zero, we choose to assume that's what is meant.
313  */
314  if (tablespaceOid == InvalidOid)
315  tablespaceOid = MyDatabaseTableSpace;
316 
317  /*
318  * Return empty string for the cluster's default tablespaces
319  */
320  if (tablespaceOid == DEFAULTTABLESPACE_OID ||
321  tablespaceOid == GLOBALTABLESPACE_OID)
323 
324 #if defined(HAVE_READLINK) || defined(WIN32)
325 
326  /*
327  * Find the location of the tablespace by reading the symbolic link that
328  * is in pg_tblspc/<oid>.
329  */
330  snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
331 
332  rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
333  if (rllen < 0)
334  ereport(ERROR,
336  errmsg("could not read symbolic link \"%s\": %m",
337  sourcepath)));
338  if (rllen >= sizeof(targetpath))
339  ereport(ERROR,
340  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
341  errmsg("symbolic link \"%s\" target is too long",
342  sourcepath)));
343  targetpath[rllen] = '\0';
344 
345  PG_RETURN_TEXT_P(cstring_to_text(targetpath));
346 #else
347  ereport(ERROR,
348  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
349  errmsg("tablespaces are not supported on this platform")));
350  PG_RETURN_NULL();
351 #endif
352 }
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
Oid MyDatabaseTableSpace
Definition: globals.c:87
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define readlink(path, buf, size)
Definition: win32_port.h:222
int errcode_for_file_access(void)
Definition: elog.c:633
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
text * cstring_to_text(const char *s)
Definition: varlena.c:172
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define snprintf
Definition: port.h:193
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_typeof()

Datum pg_typeof ( PG_FUNCTION_ARGS  )

Definition at line 480 of file misc.c.

References get_fn_expr_argtype(), and PG_RETURN_OID.

481 {
482  PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
483 }
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1804
#define PG_RETURN_OID(x)
Definition: fmgr.h:359