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 "pgstat.h"
#include "parser/scansup.h"
#include "postmaster/syslogger.h"
#include "rewrite/rewriteHandler.h"
#include "storage/fd.h"
#include "utils/lsyscache.h"
#include "utils/ruleutils.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
Include dependency graph for misc.c:

Go to the source code of this file.

Data Structures

struct  ts_db_fctx
 

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

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

◆ current_database()

Datum current_database ( PG_FUNCTION_ARGS  )

Definition at line 170 of file misc.c.

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

Referenced by ExecEvalSQLValueFunction().

171 {
172  Name db;
173 
174  db = (Name) palloc(NAMEDATALEN);
175 
177  PG_RETURN_NAME(db);
178 }
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define NAMEDATALEN
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
Definition: c.h:603
Oid MyDatabaseId
Definition: globals.c:85
void * palloc(Size size)
Definition: mcxt.c:924
NameData * Name
Definition: c.h:607
#define PG_RETURN_NAME(x)
Definition: fmgr.h:353

◆ current_query()

Datum current_query ( PG_FUNCTION_ARGS  )

Definition at line 187 of file misc.c.

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

Referenced by dblink_current_query().

188 {
189  /* there is no easy way to access the more concise 'query_string' */
190  if (debug_query_string)
192  else
193  PG_RETURN_NULL();
194 }
const char * debug_query_string
Definition: postgres.c:87
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ is_ident_cont()

static bool is_ident_cont ( unsigned char  c)
static

Definition at line 570 of file misc.c.

References is_ident_start().

Referenced by parse_ident().

571 {
572  /* Can be digit or dollar sign ... */
573  if ((c >= '0' && c <= '9') || c == '$')
574  return true;
575  /* ... or an identifier start character */
576  return is_ident_start(c);
577 }
static bool is_ident_start(unsigned char c)
Definition: misc.c:552
char * c

◆ is_ident_start()

static bool is_ident_start ( unsigned char  c)
static

Definition at line 552 of file misc.c.

References IS_HIGHBIT_SET.

Referenced by is_ident_cont(), and parse_ident().

553 {
554  /* Underscores and ASCII letters are OK */
555  if (c == '_')
556  return true;
557  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
558  return true;
559  /* Any high-bit-set character is OK (might be part of a multibyte char) */
560  if (IS_HIGHBIT_SET(c))
561  return true;
562  return false;
563 }
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1075
char * c

◆ parse_ident()

Datum parse_ident ( PG_FUNCTION_ARGS  )

Definition at line 585 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(), memmove, PG_GETARG_BOOL, PG_GETARG_TEXT_PP, PG_RETURN_DATUM, PointerGetDatum, scanner_isspace(), and text_to_cstring().

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

◆ pg_collation_for()

Datum pg_collation_for ( PG_FUNCTION_ARGS  )

Definition at line 479 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().

480 {
481  Oid typeid;
482  Oid collid;
483 
484  typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
485  if (!typeid)
486  PG_RETURN_NULL();
487  if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
488  ereport(ERROR,
489  (errcode(ERRCODE_DATATYPE_MISMATCH),
490  errmsg("collations are not supported by type %s",
491  format_type_be(typeid))));
492 
493  collid = PG_GET_COLLATION();
494  if (!collid)
495  PG_RETURN_NULL();
497 }
int errcode(int sqlerrcode)
Definition: elog.c:570
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:193
char * generate_collation_name(Oid collid)
Definition: ruleutils.c:11144
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
#define ereport(elevel, rest)
Definition: elog.h:141
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2848
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_column_is_updatable()

Datum pg_column_is_updatable ( PG_FUNCTION_ARGS  )

Definition at line 525 of file misc.c.

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

526 {
527  Oid reloid = PG_GETARG_OID(0);
530  bool include_triggers = PG_GETARG_BOOL(2);
531  int events;
532 
533  /* System columns are never updatable */
534  if (attnum <= 0)
535  PG_RETURN_BOOL(false);
536 
537  events = relation_is_updatable(reloid, include_triggers,
538  bms_make_singleton(col));
539 
540  /* We require both updatability and deletability of the relation */
541 #define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
542 
543  PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
544 }
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:186
int relation_is_updatable(Oid reloid, bool include_triggers, Bitmapset *include_cols)
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_INT16(n)
Definition: fmgr.h:266
#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 724 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().

725 {
726  FILE *fd;
727  char lbuffer[MAXPGPATH];
728  char *logfmt;
729  char *log_filepath;
730  char *log_format = lbuffer;
731  char *nlpos;
732 
733  /* The log format parameter is optional */
734  if (PG_NARGS() == 0 || PG_ARGISNULL(0))
735  logfmt = NULL;
736  else
737  {
738  logfmt = text_to_cstring(PG_GETARG_TEXT_PP(0));
739 
740  if (strcmp(logfmt, "stderr") != 0 && strcmp(logfmt, "csvlog") != 0)
741  ereport(ERROR,
742  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
743  errmsg("log format \"%s\" is not supported", logfmt),
744  errhint("The supported log formats are \"stderr\" and \"csvlog\".")));
745  }
746 
748  if (fd == NULL)
749  {
750  if (errno != ENOENT)
751  ereport(ERROR,
753  errmsg("could not read file \"%s\": %m",
755  PG_RETURN_NULL();
756  }
757 
758  /*
759  * Read the file to gather current log filename(s) registered by the
760  * syslogger.
761  */
762  while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
763  {
764  /*
765  * Extract log format and log file path from the line; lbuffer ==
766  * log_format, they share storage.
767  */
768  log_filepath = strchr(lbuffer, ' ');
769  if (log_filepath == NULL)
770  {
771  /* Uh oh. No space found, so file content is corrupted. */
772  elog(ERROR,
773  "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
774  break;
775  }
776 
777  *log_filepath = '\0';
778  log_filepath++;
779  nlpos = strchr(log_filepath, '\n');
780  if (nlpos == NULL)
781  {
782  /* Uh oh. No newline found, so file content is corrupted. */
783  elog(ERROR,
784  "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
785  break;
786  }
787  *nlpos = '\0';
788 
789  if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
790  {
791  FreeFile(fd);
792  PG_RETURN_TEXT_P(cstring_to_text(log_filepath));
793  }
794  }
795 
796  /* Close the current log filename file. */
797  FreeFile(fd);
798 
799  PG_RETURN_NULL();
800 }
int errhint(const char *fmt,...)
Definition: elog.c:974
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG_METAINFO_DATAFILE
Definition: syslogger.h:97
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2207
#define ereport(elevel, rest)
Definition: elog.h:141
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define PG_NARGS()
Definition: fmgr.h:198
int FreeFile(FILE *file)
Definition: fd.c:2406
char * text_to_cstring(const text *t)
Definition: varlena.c:204
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_current_logfile_1arg()

Datum pg_current_logfile_1arg ( PG_FUNCTION_ARGS  )

Definition at line 810 of file misc.c.

References pg_current_logfile().

811 {
812  return pg_current_logfile(fcinfo);
813 }
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition: misc.c:724

◆ pg_get_keywords()

Datum pg_get_keywords ( PG_FUNCTION_ARGS  )

Definition at line 394 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.

395 {
396  FuncCallContext *funcctx;
397 
398  if (SRF_IS_FIRSTCALL())
399  {
400  MemoryContext oldcontext;
401  TupleDesc tupdesc;
402 
403  funcctx = SRF_FIRSTCALL_INIT();
404  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
405 
406  tupdesc = CreateTemplateTupleDesc(3);
407  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
408  TEXTOID, -1, 0);
409  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
410  CHAROID, -1, 0);
411  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc",
412  TEXTOID, -1, 0);
413 
414  funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
415 
416  MemoryContextSwitchTo(oldcontext);
417  }
418 
419  funcctx = SRF_PERCALL_SETUP();
420 
421  if (funcctx->call_cntr < ScanKeywords.num_keywords)
422  {
423  char *values[3];
424  HeapTuple tuple;
425 
426  /* cast-away-const is ugly but alternatives aren't much better */
427  values[0] = unconstify(char *,
428  GetScanKeyword(funcctx->call_cntr,
429  &ScanKeywords));
430 
431  switch (ScanKeywordCategories[funcctx->call_cntr])
432  {
433  case UNRESERVED_KEYWORD:
434  values[1] = "U";
435  values[2] = _("unreserved");
436  break;
437  case COL_NAME_KEYWORD:
438  values[1] = "C";
439  values[2] = _("unreserved (cannot be function or type name)");
440  break;
442  values[1] = "T";
443  values[2] = _("reserved (can be function or type name)");
444  break;
445  case RESERVED_KEYWORD:
446  values[1] = "R";
447  values[2] = _("reserved");
448  break;
449  default: /* shouldn't be possible */
450  values[1] = NULL;
451  values[2] = NULL;
452  break;
453  }
454 
455  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
456 
457  SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
458  }
459 
460  SRF_RETURN_DONE(funcctx);
461 }
uint64 call_cntr
Definition: funcapi.h:66
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:283
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:287
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition: kwlookup.h:39
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:2112
PGDLLIMPORT const ScanKeywordList ScanKeywords
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:289
#define TYPE_FUNC_NAME_KEYWORD
Definition: keywords.h:22
AttInMetadata * attinmeta
Definition: funcapi.h:92
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:1163
int num_keywords
Definition: kwlookup.h:30
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2063
#define RESERVED_KEYWORD
Definition: keywords.h:23
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:102
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
#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:84
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:307
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:285

◆ pg_get_replica_identity_index()

Datum pg_get_replica_identity_index ( PG_FUNCTION_ARGS  )

Definition at line 819 of file misc.c.

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

820 {
821  Oid reloid = PG_GETARG_OID(0);
822  Oid idxoid;
823  Relation rel;
824 
825  rel = table_open(reloid, AccessShareLock);
826  idxoid = RelationGetReplicaIndex(rel);
828 
829  if (OidIsValid(idxoid))
830  PG_RETURN_OID(idxoid);
831  else
832  PG_RETURN_NULL();
833 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4557
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define PG_RETURN_OID(x)
Definition: fmgr.h:350
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_num_nonnulls()

Datum pg_num_nonnulls ( PG_FUNCTION_ARGS  )

Definition at line 153 of file misc.c.

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

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

◆ pg_num_nulls()

Datum pg_num_nulls ( PG_FUNCTION_ARGS  )

Definition at line 137 of file misc.c.

References count_nulls(), PG_RETURN_INT32, and PG_RETURN_NULL.

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

◆ pg_relation_is_updatable()

Datum pg_relation_is_updatable ( PG_FUNCTION_ARGS  )

Definition at line 508 of file misc.c.

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

509 {
510  Oid reloid = PG_GETARG_OID(0);
511  bool include_triggers = PG_GETARG_BOOL(1);
512 
513  PG_RETURN_INT32(relation_is_updatable(reloid, include_triggers, NULL));
514 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
unsigned int Oid
Definition: postgres_ext.h:31
int relation_is_updatable(Oid reloid, bool include_triggers, Bitmapset *include_cols)
#define PG_GETARG_OID(n)
Definition: fmgr.h:270

◆ pg_sleep()

Datum pg_sleep ( PG_FUNCTION_ARGS  )

Definition at line 346 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.

347 {
348  float8 secs = PG_GETARG_FLOAT8(0);
349  float8 endtime;
350 
351  /*
352  * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
353  * important signal (such as SIGALRM or SIGINT) arrives. Because
354  * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
355  * might ask for more than that, we sleep for at most 10 minutes and then
356  * loop.
357  *
358  * By computing the intended stop time initially, we avoid accumulation of
359  * extra delay across multiple sleeps. This also ensures we won't delay
360  * less than the specified time when WaitLatch is terminated early by a
361  * non-query-canceling signal such as SIGHUP.
362  */
363 #define GetNowFloat() ((float8) GetCurrentTimestamp() / 1000000.0)
364 
365  endtime = GetNowFloat() + secs;
366 
367  for (;;)
368  {
369  float8 delay;
370  long delay_ms;
371 
373 
374  delay = endtime - GetNowFloat();
375  if (delay >= 600.0)
376  delay_ms = 600000;
377  else if (delay > 0.0)
378  delay_ms = (long) ceil(delay * 1000.0);
379  else
380  break;
381 
382  (void) WaitLatch(MyLatch,
384  delay_ms,
387  }
388 
389  PG_RETURN_VOID();
390 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:276
#define WL_TIMEOUT
Definition: latch.h:127
void ResetLatch(Latch *latch)
Definition: latch.c:519
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:344
#define GetNowFloat()
double float8
Definition: c.h:491
#define PG_RETURN_VOID()
Definition: fmgr.h:339
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 205 of file misc.c.

References AllocateDir(), atooid, dirent::d_name, ts_db_fctx::dirdesc, directory_is_empty(), ereport, errcode_for_file_access(), errmsg(), ERROR, FreeDir(), ts_db_fctx::location, MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, ObjectIdGetDatum, palloc(), pfree(), PG_GETARG_OID, psprintf(), ReadDir(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, TABLESPACE_VERSION_DIRECTORY, FuncCallContext::user_fctx, and WARNING.

206 {
207  FuncCallContext *funcctx;
208  struct dirent *de;
209  ts_db_fctx *fctx;
210 
211  if (SRF_IS_FIRSTCALL())
212  {
213  MemoryContext oldcontext;
214  Oid tablespaceOid = PG_GETARG_OID(0);
215 
216  funcctx = SRF_FIRSTCALL_INIT();
217  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
218 
219  fctx = palloc(sizeof(ts_db_fctx));
220 
221  if (tablespaceOid == GLOBALTABLESPACE_OID)
222  {
223  fctx->dirdesc = NULL;
225  (errmsg("global tablespace never has databases")));
226  }
227  else
228  {
229  if (tablespaceOid == DEFAULTTABLESPACE_OID)
230  fctx->location = psprintf("base");
231  else
232  fctx->location = psprintf("pg_tblspc/%u/%s", tablespaceOid,
234 
235  fctx->dirdesc = AllocateDir(fctx->location);
236 
237  if (!fctx->dirdesc)
238  {
239  /* the only expected error is ENOENT */
240  if (errno != ENOENT)
241  ereport(ERROR,
243  errmsg("could not open directory \"%s\": %m",
244  fctx->location)));
246  (errmsg("%u is not a tablespace OID", tablespaceOid)));
247  }
248  }
249  funcctx->user_fctx = fctx;
250  MemoryContextSwitchTo(oldcontext);
251  }
252 
253  funcctx = SRF_PERCALL_SETUP();
254  fctx = (ts_db_fctx *) funcctx->user_fctx;
255 
256  if (!fctx->dirdesc) /* not a tablespace */
257  SRF_RETURN_DONE(funcctx);
258 
259  while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
260  {
261  Oid datOid = atooid(de->d_name);
262  char *subdir;
263  bool isempty;
264 
265  /* this test skips . and .., but is awfully weak */
266  if (!datOid)
267  continue;
268 
269  /* if database subdir is empty, don't report tablespace as used */
270 
271  subdir = psprintf("%s/%s", fctx->location, de->d_name);
272  isempty = directory_is_empty(subdir);
273  pfree(subdir);
274 
275  if (isempty)
276  continue; /* indeed, nothing in it */
277 
278  SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(datOid));
279  }
280 
281  FreeDir(fctx->dirdesc);
282  SRF_RETURN_DONE(funcctx);
283 }
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:283
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool directory_is_empty(const char *path)
Definition: tablespace.c:847
unsigned int Oid
Definition: postgres_ext.h:31
Definition: dirent.h:9
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:287
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:289
void pfree(void *pointer)
Definition: mcxt.c:1031
#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:270
int errcode_for_file_access(void)
Definition: elog.c:593
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
#define atooid(x)
Definition: postgres_ext.h:42
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2534
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:102
void * user_fctx
Definition: funcapi.h:83
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
char d_name[MAX_PATH]
Definition: dirent.h:14
char * location
Definition: misc.c:200
DIR * dirdesc
Definition: misc.c:201
int FreeDir(DIR *dir)
Definition: fd.c:2586
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:307
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:285

◆ pg_tablespace_location()

Datum pg_tablespace_location ( PG_FUNCTION_ARGS  )

Definition at line 290 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.

291 {
292  Oid tablespaceOid = PG_GETARG_OID(0);
293  char sourcepath[MAXPGPATH];
294  char targetpath[MAXPGPATH];
295  int rllen;
296 
297  /*
298  * It's useful to apply this function to pg_class.reltablespace, wherein
299  * zero means "the database's default tablespace". So, rather than
300  * throwing an error for zero, we choose to assume that's what is meant.
301  */
302  if (tablespaceOid == InvalidOid)
303  tablespaceOid = MyDatabaseTableSpace;
304 
305  /*
306  * Return empty string for the cluster's default tablespaces
307  */
308  if (tablespaceOid == DEFAULTTABLESPACE_OID ||
309  tablespaceOid == GLOBALTABLESPACE_OID)
311 
312 #if defined(HAVE_READLINK) || defined(WIN32)
313 
314  /*
315  * Find the location of the tablespace by reading the symbolic link that
316  * is in pg_tblspc/<oid>.
317  */
318  snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
319 
320  rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
321  if (rllen < 0)
322  ereport(ERROR,
324  errmsg("could not read symbolic link \"%s\": %m",
325  sourcepath)));
326  if (rllen >= sizeof(targetpath))
327  ereport(ERROR,
328  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
329  errmsg("symbolic link \"%s\" target is too long",
330  sourcepath)));
331  targetpath[rllen] = '\0';
332 
333  PG_RETURN_TEXT_P(cstring_to_text(targetpath));
334 #else
335  ereport(ERROR,
336  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
337  errmsg("tablespaces are not supported on this platform")));
338  PG_RETURN_NULL();
339 #endif
340 }
int errcode(int sqlerrcode)
Definition: elog.c:570
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:270
#define readlink(path, buf, size)
Definition: win32_port.h:231
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define snprintf
Definition: port.h:192
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_typeof()

Datum pg_typeof ( PG_FUNCTION_ARGS  )

Definition at line 468 of file misc.c.

References get_fn_expr_argtype(), and PG_RETURN_OID.

469 {
470  PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
471 }
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
#define PG_RETURN_OID(x)
Definition: fmgr.h:350