PostgreSQL Source Code  git master
misc.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * misc.c
4  *
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/utils/adt/misc.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include <sys/file.h>
18 #include <signal.h>
19 #include <dirent.h>
20 #include <math.h>
21 #include <unistd.h>
22 
23 #include "access/sysattr.h"
24 #include "catalog/pg_authid.h"
25 #include "catalog/catalog.h"
26 #include "catalog/pg_tablespace.h"
27 #include "catalog/pg_type.h"
28 #include "commands/dbcommands.h"
29 #include "commands/tablespace.h"
30 #include "common/keywords.h"
31 #include "funcapi.h"
32 #include "miscadmin.h"
33 #include "pgstat.h"
34 #include "parser/scansup.h"
35 #include "postmaster/syslogger.h"
36 #include "rewrite/rewriteHandler.h"
37 #include "storage/fd.h"
38 #include "storage/pmsignal.h"
39 #include "storage/proc.h"
40 #include "storage/procarray.h"
41 #include "utils/lsyscache.h"
42 #include "utils/ruleutils.h"
43 #include "tcop/tcopprot.h"
44 #include "utils/acl.h"
45 #include "utils/builtins.h"
46 #include "utils/timestamp.h"
47 
48 
49 /*
50  * Common subroutine for num_nulls() and num_nonnulls().
51  * Returns true if successful, false if function should return NULL.
52  * If successful, total argument count and number of nulls are
53  * returned into *nargs and *nulls.
54  */
55 static bool
57  int32 *nargs, int32 *nulls)
58 {
59  int32 count = 0;
60  int i;
61 
62  /* Did we get a VARIADIC array argument, or separate arguments? */
63  if (get_fn_expr_variadic(fcinfo->flinfo))
64  {
65  ArrayType *arr;
66  int ndims,
67  nitems,
68  *dims;
69  bits8 *bitmap;
70 
71  Assert(PG_NARGS() == 1);
72 
73  /*
74  * If we get a null as VARIADIC array argument, we can't say anything
75  * useful about the number of elements, so return NULL. This behavior
76  * is consistent with other variadic functions - see concat_internal.
77  */
78  if (PG_ARGISNULL(0))
79  return false;
80 
81  /*
82  * Non-null argument had better be an array. We assume that any call
83  * context that could let get_fn_expr_variadic return true will have
84  * checked that a VARIADIC-labeled parameter actually is an array. So
85  * it should be okay to just Assert that it's an array rather than
86  * doing a full-fledged error check.
87  */
89 
90  /* OK, safe to fetch the array value */
91  arr = PG_GETARG_ARRAYTYPE_P(0);
92 
93  /* Count the array elements */
94  ndims = ARR_NDIM(arr);
95  dims = ARR_DIMS(arr);
96  nitems = ArrayGetNItems(ndims, dims);
97 
98  /* Count those that are NULL */
99  bitmap = ARR_NULLBITMAP(arr);
100  if (bitmap)
101  {
102  int bitmask = 1;
103 
104  for (i = 0; i < nitems; i++)
105  {
106  if ((*bitmap & bitmask) == 0)
107  count++;
108 
109  bitmask <<= 1;
110  if (bitmask == 0x100)
111  {
112  bitmap++;
113  bitmask = 1;
114  }
115  }
116  }
117 
118  *nargs = nitems;
119  *nulls = count;
120  }
121  else
122  {
123  /* Separate arguments, so just count 'em */
124  for (i = 0; i < PG_NARGS(); i++)
125  {
126  if (PG_ARGISNULL(i))
127  count++;
128  }
129 
130  *nargs = PG_NARGS();
131  *nulls = count;
132  }
133 
134  return true;
135 }
136 
137 /*
138  * num_nulls()
139  * Count the number of NULL arguments
140  */
141 Datum
143 {
144  int32 nargs,
145  nulls;
146 
147  if (!count_nulls(fcinfo, &nargs, &nulls))
148  PG_RETURN_NULL();
149 
150  PG_RETURN_INT32(nulls);
151 }
152 
153 /*
154  * num_nonnulls()
155  * Count the number of non-NULL arguments
156  */
157 Datum
159 {
160  int32 nargs,
161  nulls;
162 
163  if (!count_nulls(fcinfo, &nargs, &nulls))
164  PG_RETURN_NULL();
165 
166  PG_RETURN_INT32(nargs - nulls);
167 }
168 
169 
170 /*
171  * current_database()
172  * Expose the current database to the user
173  */
174 Datum
176 {
177  Name db;
178 
179  db = (Name) palloc(NAMEDATALEN);
180 
182  PG_RETURN_NAME(db);
183 }
184 
185 
186 /*
187  * current_query()
188  * Expose the current query to the user (useful in stored procedures)
189  * We might want to use ActivePortal->sourceText someday.
190  */
191 Datum
193 {
194  /* there is no easy way to access the more concise 'query_string' */
195  if (debug_query_string)
197  else
198  PG_RETURN_NULL();
199 }
200 
201 /*
202  * Send a signal to another backend.
203  *
204  * The signal is delivered if the user is either a superuser or the same
205  * role as the backend being signaled. For "dangerous" signals, an explicit
206  * check for superuser needs to be done prior to calling this function.
207  *
208  * Returns 0 on success, 1 on general failure, 2 on normal permission error
209  * and 3 if the caller needs to be a superuser.
210  *
211  * In the event of a general failure (return code 1), a warning message will
212  * be emitted. For permission errors, doing that is the responsibility of
213  * the caller.
214  */
215 #define SIGNAL_BACKEND_SUCCESS 0
216 #define SIGNAL_BACKEND_ERROR 1
217 #define SIGNAL_BACKEND_NOPERMISSION 2
218 #define SIGNAL_BACKEND_NOSUPERUSER 3
219 static int
220 pg_signal_backend(int pid, int sig)
221 {
222  PGPROC *proc = BackendPidGetProc(pid);
223 
224  /*
225  * BackendPidGetProc returns NULL if the pid isn't valid; but by the time
226  * we reach kill(), a process for which we get a valid proc here might
227  * have terminated on its own. There's no way to acquire a lock on an
228  * arbitrary process to prevent that. But since so far all the callers of
229  * this mechanism involve some request for ending the process anyway, that
230  * it might end on its own first is not a problem.
231  */
232  if (proc == NULL)
233  {
234  /*
235  * This is just a warning so a loop-through-resultset will not abort
236  * if one backend terminated on its own during the run.
237  */
239  (errmsg("PID %d is not a PostgreSQL server process", pid)));
240  return SIGNAL_BACKEND_ERROR;
241  }
242 
243  /* Only allow superusers to signal superuser-owned backends. */
244  if (superuser_arg(proc->roleId) && !superuser())
246 
247  /* Users can signal backends they have role membership in. */
248  if (!has_privs_of_role(GetUserId(), proc->roleId) &&
251 
252  /*
253  * Can the process we just validated above end, followed by the pid being
254  * recycled for a new process, before reaching here? Then we'd be trying
255  * to kill the wrong thing. Seems near impossible when sequential pid
256  * assignment and wraparound is used. Perhaps it could happen on a system
257  * where pid re-use is randomized. That race condition possibility seems
258  * too unlikely to worry about.
259  */
260 
261  /* If we have setsid(), signal the backend's whole process group */
262 #ifdef HAVE_SETSID
263  if (kill(-pid, sig))
264 #else
265  if (kill(pid, sig))
266 #endif
267  {
268  /* Again, just a warning to allow loops */
270  (errmsg("could not send signal to process %d: %m", pid)));
271  return SIGNAL_BACKEND_ERROR;
272  }
273  return SIGNAL_BACKEND_SUCCESS;
274 }
275 
276 /*
277  * Signal to cancel a backend process. This is allowed if you are a member of
278  * the role whose process is being canceled.
279  *
280  * Note that only superusers can signal superuser-owned processes.
281  */
282 Datum
284 {
285  int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT);
286 
288  ereport(ERROR,
289  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
290  (errmsg("must be a superuser to cancel superuser query"))));
291 
293  ereport(ERROR,
294  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
295  (errmsg("must be a member of the role whose query is being canceled or member of pg_signal_backend"))));
296 
298 }
299 
300 /*
301  * Signal to terminate a backend process. This is allowed if you are a member
302  * of the role whose process is being terminated.
303  *
304  * Note that only superusers can signal superuser-owned processes.
305  */
306 Datum
308 {
309  int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM);
310 
312  ereport(ERROR,
313  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
314  (errmsg("must be a superuser to terminate superuser process"))));
315 
317  ereport(ERROR,
318  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
319  (errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend"))));
320 
322 }
323 
324 /*
325  * Signal to reload the database configuration
326  *
327  * Permission checking for this function is managed through the normal
328  * GRANT system.
329  */
330 Datum
332 {
333  if (kill(PostmasterPid, SIGHUP))
334  {
336  (errmsg("failed to send signal to postmaster: %m")));
337  PG_RETURN_BOOL(false);
338  }
339 
340  PG_RETURN_BOOL(true);
341 }
342 
343 
344 /*
345  * Rotate log file
346  *
347  * Permission checking for this function is managed through the normal
348  * GRANT system.
349  */
350 Datum
352 {
353  if (!Logging_collector)
354  {
356  (errmsg("rotation not possible because log collection not active")));
357  PG_RETURN_BOOL(false);
358  }
359 
361  PG_RETURN_BOOL(true);
362 }
363 
364 /* Function to find out which databases make use of a tablespace */
365 
366 typedef struct
367 {
368  char *location;
370 } ts_db_fctx;
371 
372 Datum
374 {
375  FuncCallContext *funcctx;
376  struct dirent *de;
377  ts_db_fctx *fctx;
378 
379  if (SRF_IS_FIRSTCALL())
380  {
381  MemoryContext oldcontext;
382  Oid tablespaceOid = PG_GETARG_OID(0);
383 
384  funcctx = SRF_FIRSTCALL_INIT();
385  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
386 
387  fctx = palloc(sizeof(ts_db_fctx));
388 
389  if (tablespaceOid == GLOBALTABLESPACE_OID)
390  {
391  fctx->dirdesc = NULL;
393  (errmsg("global tablespace never has databases")));
394  }
395  else
396  {
397  if (tablespaceOid == DEFAULTTABLESPACE_OID)
398  fctx->location = psprintf("base");
399  else
400  fctx->location = psprintf("pg_tblspc/%u/%s", tablespaceOid,
402 
403  fctx->dirdesc = AllocateDir(fctx->location);
404 
405  if (!fctx->dirdesc)
406  {
407  /* the only expected error is ENOENT */
408  if (errno != ENOENT)
409  ereport(ERROR,
411  errmsg("could not open directory \"%s\": %m",
412  fctx->location)));
414  (errmsg("%u is not a tablespace OID", tablespaceOid)));
415  }
416  }
417  funcctx->user_fctx = fctx;
418  MemoryContextSwitchTo(oldcontext);
419  }
420 
421  funcctx = SRF_PERCALL_SETUP();
422  fctx = (ts_db_fctx *) funcctx->user_fctx;
423 
424  if (!fctx->dirdesc) /* not a tablespace */
425  SRF_RETURN_DONE(funcctx);
426 
427  while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
428  {
429  Oid datOid = atooid(de->d_name);
430  char *subdir;
431  bool isempty;
432 
433  /* this test skips . and .., but is awfully weak */
434  if (!datOid)
435  continue;
436 
437  /* if database subdir is empty, don't report tablespace as used */
438 
439  subdir = psprintf("%s/%s", fctx->location, de->d_name);
440  isempty = directory_is_empty(subdir);
441  pfree(subdir);
442 
443  if (isempty)
444  continue; /* indeed, nothing in it */
445 
446  SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(datOid));
447  }
448 
449  FreeDir(fctx->dirdesc);
450  SRF_RETURN_DONE(funcctx);
451 }
452 
453 
454 /*
455  * pg_tablespace_location - get location for a tablespace
456  */
457 Datum
459 {
460  Oid tablespaceOid = PG_GETARG_OID(0);
461  char sourcepath[MAXPGPATH];
462  char targetpath[MAXPGPATH];
463  int rllen;
464 
465  /*
466  * It's useful to apply this function to pg_class.reltablespace, wherein
467  * zero means "the database's default tablespace". So, rather than
468  * throwing an error for zero, we choose to assume that's what is meant.
469  */
470  if (tablespaceOid == InvalidOid)
471  tablespaceOid = MyDatabaseTableSpace;
472 
473  /*
474  * Return empty string for the cluster's default tablespaces
475  */
476  if (tablespaceOid == DEFAULTTABLESPACE_OID ||
477  tablespaceOid == GLOBALTABLESPACE_OID)
479 
480 #if defined(HAVE_READLINK) || defined(WIN32)
481 
482  /*
483  * Find the location of the tablespace by reading the symbolic link that
484  * is in pg_tblspc/<oid>.
485  */
486  snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
487 
488  rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
489  if (rllen < 0)
490  ereport(ERROR,
492  errmsg("could not read symbolic link \"%s\": %m",
493  sourcepath)));
494  if (rllen >= sizeof(targetpath))
495  ereport(ERROR,
496  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
497  errmsg("symbolic link \"%s\" target is too long",
498  sourcepath)));
499  targetpath[rllen] = '\0';
500 
501  PG_RETURN_TEXT_P(cstring_to_text(targetpath));
502 #else
503  ereport(ERROR,
504  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
505  errmsg("tablespaces are not supported on this platform")));
506  PG_RETURN_NULL();
507 #endif
508 }
509 
510 /*
511  * pg_sleep - delay for N seconds
512  */
513 Datum
515 {
516  float8 secs = PG_GETARG_FLOAT8(0);
517  float8 endtime;
518 
519  /*
520  * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
521  * important signal (such as SIGALRM or SIGINT) arrives. Because
522  * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
523  * might ask for more than that, we sleep for at most 10 minutes and then
524  * loop.
525  *
526  * By computing the intended stop time initially, we avoid accumulation of
527  * extra delay across multiple sleeps. This also ensures we won't delay
528  * less than the specified time when WaitLatch is terminated early by a
529  * non-query-canceling signal such as SIGHUP.
530  */
531 #define GetNowFloat() ((float8) GetCurrentTimestamp() / 1000000.0)
532 
533  endtime = GetNowFloat() + secs;
534 
535  for (;;)
536  {
537  float8 delay;
538  long delay_ms;
539 
541 
542  delay = endtime - GetNowFloat();
543  if (delay >= 600.0)
544  delay_ms = 600000;
545  else if (delay > 0.0)
546  delay_ms = (long) ceil(delay * 1000.0);
547  else
548  break;
549 
550  (void) WaitLatch(MyLatch,
552  delay_ms,
555  }
556 
557  PG_RETURN_VOID();
558 }
559 
560 /* Function to return the list of grammar keywords */
561 Datum
563 {
564  FuncCallContext *funcctx;
565 
566  if (SRF_IS_FIRSTCALL())
567  {
568  MemoryContext oldcontext;
569  TupleDesc tupdesc;
570 
571  funcctx = SRF_FIRSTCALL_INIT();
572  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
573 
574  tupdesc = CreateTemplateTupleDesc(3, false);
575  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
576  TEXTOID, -1, 0);
577  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
578  CHAROID, -1, 0);
579  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc",
580  TEXTOID, -1, 0);
581 
582  funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
583 
584  MemoryContextSwitchTo(oldcontext);
585  }
586 
587  funcctx = SRF_PERCALL_SETUP();
588 
589  if (funcctx->call_cntr < NumScanKeywords)
590  {
591  char *values[3];
592  HeapTuple tuple;
593 
594  /* cast-away-const is ugly but alternatives aren't much better */
595  values[0] = (char *) ScanKeywords[funcctx->call_cntr].name;
596 
597  switch (ScanKeywords[funcctx->call_cntr].category)
598  {
599  case UNRESERVED_KEYWORD:
600  values[1] = "U";
601  values[2] = _("unreserved");
602  break;
603  case COL_NAME_KEYWORD:
604  values[1] = "C";
605  values[2] = _("unreserved (cannot be function or type name)");
606  break;
608  values[1] = "T";
609  values[2] = _("reserved (can be function or type name)");
610  break;
611  case RESERVED_KEYWORD:
612  values[1] = "R";
613  values[2] = _("reserved");
614  break;
615  default: /* shouldn't be possible */
616  values[1] = NULL;
617  values[2] = NULL;
618  break;
619  }
620 
621  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
622 
623  SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
624  }
625 
626  SRF_RETURN_DONE(funcctx);
627 }
628 
629 
630 /*
631  * Return the type of the argument.
632  */
633 Datum
635 {
636  PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
637 }
638 
639 
640 /*
641  * Implementation of the COLLATE FOR expression; returns the collation
642  * of the argument.
643  */
644 Datum
646 {
647  Oid typeid;
648  Oid collid;
649 
650  typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
651  if (!typeid)
652  PG_RETURN_NULL();
653  if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
654  ereport(ERROR,
655  (errcode(ERRCODE_DATATYPE_MISMATCH),
656  errmsg("collations are not supported by type %s",
657  format_type_be(typeid))));
658 
659  collid = PG_GET_COLLATION();
660  if (!collid)
661  PG_RETURN_NULL();
663 }
664 
665 
666 /*
667  * pg_relation_is_updatable - determine which update events the specified
668  * relation supports.
669  *
670  * This relies on relation_is_updatable() in rewriteHandler.c, which see
671  * for additional information.
672  */
673 Datum
675 {
676  Oid reloid = PG_GETARG_OID(0);
677  bool include_triggers = PG_GETARG_BOOL(1);
678 
679  PG_RETURN_INT32(relation_is_updatable(reloid, include_triggers, NULL));
680 }
681 
682 /*
683  * pg_column_is_updatable - determine whether a column is updatable
684  *
685  * This function encapsulates the decision about just what
686  * information_schema.columns.is_updatable actually means. It's not clear
687  * whether deletability of the column's relation should be required, so
688  * we want that decision in C code where we could change it without initdb.
689  */
690 Datum
692 {
693  Oid reloid = PG_GETARG_OID(0);
694  AttrNumber attnum = PG_GETARG_INT16(1);
696  bool include_triggers = PG_GETARG_BOOL(2);
697  int events;
698 
699  /* System columns are never updatable */
700  if (attnum <= 0)
701  PG_RETURN_BOOL(false);
702 
703  events = relation_is_updatable(reloid, include_triggers,
704  bms_make_singleton(col));
705 
706  /* We require both updatability and deletability of the relation */
707 #define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
708 
709  PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
710 }
711 
712 
713 /*
714  * Is character a valid identifier start?
715  * Must match scan.l's {ident_start} character class.
716  */
717 static bool
718 is_ident_start(unsigned char c)
719 {
720  /* Underscores and ASCII letters are OK */
721  if (c == '_')
722  return true;
723  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
724  return true;
725  /* Any high-bit-set character is OK (might be part of a multibyte char) */
726  if (IS_HIGHBIT_SET(c))
727  return true;
728  return false;
729 }
730 
731 /*
732  * Is character a valid identifier continuation?
733  * Must match scan.l's {ident_cont} character class.
734  */
735 static bool
736 is_ident_cont(unsigned char c)
737 {
738  /* Can be digit or dollar sign ... */
739  if ((c >= '0' && c <= '9') || c == '$')
740  return true;
741  /* ... or an identifier start character */
742  return is_ident_start(c);
743 }
744 
745 /*
746  * parse_ident - parse a SQL qualified identifier into separate identifiers.
747  * When strict mode is active (second parameter), then any chars after
748  * the last identifier are disallowed.
749  */
750 Datum
752 {
753  text *qualname = PG_GETARG_TEXT_PP(0);
754  bool strict = PG_GETARG_BOOL(1);
755  char *qualname_str = text_to_cstring(qualname);
756  ArrayBuildState *astate = NULL;
757  char *nextp;
758  bool after_dot = false;
759 
760  /*
761  * The code below scribbles on qualname_str in some cases, so we should
762  * reconvert qualname if we need to show the original string in error
763  * messages.
764  */
765  nextp = qualname_str;
766 
767  /* skip leading whitespace */
768  while (scanner_isspace(*nextp))
769  nextp++;
770 
771  for (;;)
772  {
773  char *curname;
774  bool missing_ident = true;
775 
776  if (*nextp == '"')
777  {
778  char *endp;
779 
780  curname = nextp + 1;
781  for (;;)
782  {
783  endp = strchr(nextp + 1, '"');
784  if (endp == NULL)
785  ereport(ERROR,
786  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
787  errmsg("string is not a valid identifier: \"%s\"",
788  text_to_cstring(qualname)),
789  errdetail("String has unclosed double quotes.")));
790  if (endp[1] != '"')
791  break;
792  memmove(endp, endp + 1, strlen(endp));
793  nextp = endp;
794  }
795  nextp = endp + 1;
796  *endp = '\0';
797 
798  if (endp - curname == 0)
799  ereport(ERROR,
800  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
801  errmsg("string is not a valid identifier: \"%s\"",
802  text_to_cstring(qualname)),
803  errdetail("Quoted identifier must not be empty.")));
804 
805  astate = accumArrayResult(astate, CStringGetTextDatum(curname),
806  false, TEXTOID, CurrentMemoryContext);
807  missing_ident = false;
808  }
809  else if (is_ident_start((unsigned char) *nextp))
810  {
811  char *downname;
812  int len;
813  text *part;
814 
815  curname = nextp++;
816  while (is_ident_cont((unsigned char) *nextp))
817  nextp++;
818 
819  len = nextp - curname;
820 
821  /*
822  * We don't implicitly truncate identifiers. This is useful for
823  * allowing the user to check for specific parts of the identifier
824  * being too long. It's easy enough for the user to get the
825  * truncated names by casting our output to name[].
826  */
827  downname = downcase_identifier(curname, len, false, false);
828  part = cstring_to_text_with_len(downname, len);
829  astate = accumArrayResult(astate, PointerGetDatum(part), false,
831  missing_ident = false;
832  }
833 
834  if (missing_ident)
835  {
836  /* Different error messages based on where we failed. */
837  if (*nextp == '.')
838  ereport(ERROR,
839  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
840  errmsg("string is not a valid identifier: \"%s\"",
841  text_to_cstring(qualname)),
842  errdetail("No valid identifier before \".\".")));
843  else if (after_dot)
844  ereport(ERROR,
845  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
846  errmsg("string is not a valid identifier: \"%s\"",
847  text_to_cstring(qualname)),
848  errdetail("No valid identifier after \".\".")));
849  else
850  ereport(ERROR,
851  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
852  errmsg("string is not a valid identifier: \"%s\"",
853  text_to_cstring(qualname))));
854  }
855 
856  while (scanner_isspace(*nextp))
857  nextp++;
858 
859  if (*nextp == '.')
860  {
861  after_dot = true;
862  nextp++;
863  while (scanner_isspace(*nextp))
864  nextp++;
865  }
866  else if (*nextp == '\0')
867  {
868  break;
869  }
870  else
871  {
872  if (strict)
873  ereport(ERROR,
874  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
875  errmsg("string is not a valid identifier: \"%s\"",
876  text_to_cstring(qualname))));
877  break;
878  }
879  }
880 
882 }
883 
884 /*
885  * pg_current_logfile
886  *
887  * Report current log file used by log collector by scanning current_logfiles.
888  */
889 Datum
891 {
892  FILE *fd;
893  char lbuffer[MAXPGPATH];
894  char *logfmt;
895  char *log_filepath;
896  char *log_format = lbuffer;
897  char *nlpos;
898 
899  /* The log format parameter is optional */
900  if (PG_NARGS() == 0 || PG_ARGISNULL(0))
901  logfmt = NULL;
902  else
903  {
904  logfmt = text_to_cstring(PG_GETARG_TEXT_PP(0));
905 
906  if (strcmp(logfmt, "stderr") != 0 && strcmp(logfmt, "csvlog") != 0)
907  ereport(ERROR,
908  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
909  errmsg("log format \"%s\" is not supported", logfmt),
910  errhint("The supported log formats are \"stderr\" and \"csvlog\".")));
911  }
912 
914  if (fd == NULL)
915  {
916  if (errno != ENOENT)
917  ereport(ERROR,
919  errmsg("could not read file \"%s\": %m",
921  PG_RETURN_NULL();
922  }
923 
924  /*
925  * Read the file to gather current log filename(s) registered by the
926  * syslogger.
927  */
928  while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
929  {
930  /*
931  * Extract log format and log file path from the line; lbuffer ==
932  * log_format, they share storage.
933  */
934  log_filepath = strchr(lbuffer, ' ');
935  if (log_filepath == NULL)
936  {
937  /* Uh oh. No space found, so file content is corrupted. */
938  elog(ERROR,
939  "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
940  break;
941  }
942 
943  *log_filepath = '\0';
944  log_filepath++;
945  nlpos = strchr(log_filepath, '\n');
946  if (nlpos == NULL)
947  {
948  /* Uh oh. No newline found, so file content is corrupted. */
949  elog(ERROR,
950  "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
951  break;
952  }
953  *nlpos = '\0';
954 
955  if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
956  {
957  FreeFile(fd);
958  PG_RETURN_TEXT_P(cstring_to_text(log_filepath));
959  }
960  }
961 
962  /* Close the current log filename file. */
963  FreeFile(fd);
964 
965  PG_RETURN_NULL();
966 }
967 
968 /*
969  * Report current log file used by log collector (1 argument version)
970  *
971  * note: this wrapper is necessary to pass the sanity check in opr_sanity,
972  * which checks that all built-in functions that share the implementing C
973  * function take the same number of arguments
974  */
975 Datum
977 {
978  return pg_current_logfile(fcinfo);
979 }
980 
981 /*
982  * SQL wrapper around RelationGetReplicaIndex().
983  */
984 Datum
986 {
987  Oid reloid = PG_GETARG_OID(0);
988  Oid idxoid;
989  Relation rel;
990 
991  rel = heap_open(reloid, AccessShareLock);
992  idxoid = RelationGetReplicaIndex(rel);
994 
995  if (OidIsValid(idxoid))
996  PG_RETURN_OID(idxoid);
997  else
998  PG_RETURN_NULL();
999 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:246
#define DEFAULT_ROLE_SIGNAL_BACKENDID
Definition: pg_authid.h:112
uint64 call_cntr
Definition: funcapi.h:66
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
static bool is_ident_start(unsigned char c)
Definition: misc.c:718
Datum pg_get_replica_identity_index(PG_FUNCTION_ARGS)
Definition: misc.c:985
Datum pg_rotate_logfile(PG_FUNCTION_ARGS)
Definition: misc.c:351
int errhint(const char *fmt,...)
Definition: elog.c:987
Datum pg_relation_is_updatable(PG_FUNCTION_ARGS)
Definition: misc.c:674
Datum parse_ident(PG_FUNCTION_ARGS)
Definition: misc.c:751
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4691
#define WL_TIMEOUT
Definition: latch.h:127
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition: misc.c:56
Oid GetUserId(void)
Definition: miscinit.c:284
#define TEXTOID
Definition: pg_type.h:324
PGPROC * BackendPidGetProc(int pid)
Definition: procarray.c:2346
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:293
#define PointerGetDatum(X)
Definition: postgres.h:562
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
const int NumScanKeywords
Definition: keywords.c:45
#define AccessShareLock
Definition: lockdefs.h:36
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
Datum pg_collation_for(PG_FUNCTION_ARGS)
Definition: misc.c:645
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2038
Oid roleId
Definition: proc.h:115
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
#define LOG_METAINFO_DATAFILE
Definition: syslogger.h:94
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define kill(pid, sig)
Definition: win32_port.h:437
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool directory_is_empty(const char *path)
Definition: tablespace.c:831
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
#define UNRESERVED_KEYWORD
Definition: keywords.h:18
#define heap_close(r, l)
Definition: heapam.h:97
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
void ResetLatch(volatile Latch *latch)
Definition: latch.c:497
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:216
Definition: dirent.h:9
#define OidIsValid(objectId)
Definition: c.h:576
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:297
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_GET_COLLATION()
Definition: fmgr.h:163
Datum pg_typeof(PG_FUNCTION_ARGS)
Definition: misc.c:634
char * generate_collation_name(Oid collid)
Definition: ruleutils.c:10856
signed int int32
Definition: c.h:284
Oid MyDatabaseTableSpace
Definition: globals.c:79
bool Logging_collector
Definition: syslogger.c:63
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:1118
Datum current_database(PG_FUNCTION_ARGS)
Definition: misc.c:175
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
Datum current_query(PG_FUNCTION_ARGS)
Definition: misc.c:192
#define NAMEDATALEN
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
FmgrInfo * flinfo
Definition: fmgr.h:79
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
#define GetNowFloat()
int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:336
void pfree(void *pointer)
Definition: mcxt.c:949
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition: misc.c:890
#define IS_HIGHBIT_SET(ch)
Definition: c.h:939
Datum pg_tablespace_location(PG_FUNCTION_ARGS)
Definition: misc.c:458
Definition: dirent.c:25
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:429
Datum pg_num_nulls(PG_FUNCTION_ARGS)
Definition: misc.c:142
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
#define SIGNAL_BACKEND_SUCCESS
Definition: misc.c:215
#define ARR_DIMS(a)
Definition: array.h:279
#define MAXPGPATH
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
Definition: c.h:541
#define TYPE_FUNC_NAME_KEYWORD
Definition: keywords.h:20
char * c
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:179
int relation_is_updatable(Oid reloid, bool include_triggers, Bitmapset *include_cols)
const ScanKeyword ScanKeywords[]
Definition: keywords.c:41
#define memmove(d, s, c)
Definition: c.h:1045
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:161
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define readlink(path, buf, size)
Definition: win32_port.h:233
AttInMetadata * attinmeta
Definition: funcapi.h:100
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
const char * name
Definition: keywords.h:26
int errdetail(const char *fmt,...)
Definition: elog.c:873
int errcode_for_file_access(void)
Definition: elog.c:598
#define SIGHUP
Definition: win32_port.h:163
Datum pg_terminate_backend(PG_FUNCTION_ARGS)
Definition: misc.c:307
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2342
Datum pg_current_logfile_1arg(PG_FUNCTION_ARGS)
Definition: misc.c:976
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2596
Datum pg_sleep(PG_FUNCTION_ARGS)
Definition: misc.c:514
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define SIGNAL_BACKEND_NOPERMISSION
Definition: misc.c:217
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:505
#define atooid(x)
Definition: postgres_ext.h:42
Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
Definition: misc.c:373
#define ereport(elevel, rest)
Definition: elog.h:122
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5106
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
pid_t PostmasterPid
Definition: globals.c:87
#define WARNING
Definition: elog.h:40
const char * debug_query_string
Definition: postgres.c:85
Datum pg_num_nonnulls(PG_FUNCTION_ARGS)
Definition: misc.c:158
uint8 bits8
Definition: c.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:313
Datum pg_reload_conf(PG_FUNCTION_ARGS)
Definition: misc.c:331
Oid MyDatabaseId
Definition: globals.c:77
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:1069
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
bool scanner_isspace(char ch)
Definition: scansup.c:221
#define PG_GETARG_INT16(n)
Definition: fmgr.h:236
#define REQ_EVENTS
static int sig
Definition: pg_ctl.c:80
#define RESERVED_KEYWORD
Definition: keywords.h:21
#define CHAROID
Definition: pg_type.h:296
#define InvalidOid
Definition: postgres_ext.h:36
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition: scansup.c:140
Datum pg_cancel_backend(PG_FUNCTION_ARGS)
Definition: misc.c:283
#define SIGNAL_BACKEND_NOSUPERUSER
Definition: misc.c:218
#define PG_RETURN_VOID()
Definition: fmgr.h:309
static int pg_signal_backend(int pid, int sig)
Definition: misc.c:220
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define Assert(condition)
Definition: c.h:670
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2662
int16 category
Definition: keywords.h:28
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:110
static bool is_ident_cont(unsigned char c)
Definition: misc.c:736
#define PG_NARGS()
Definition: fmgr.h:168
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:230
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:43
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
#define ARR_NDIM(a)
Definition: array.h:275
#define UNKNOWNOID
Definition: pg_type.h:431
#define COL_NAME_KEYWORD
Definition: keywords.h:19
int FreeFile(FILE *file)
Definition: fd.c:2534
static Datum values[MAXATTR]
Definition: bootstrap.c:164
char * text_to_cstring(const text *t)
Definition: varlena.c:182
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5042
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2590
void * user_fctx
Definition: funcapi.h:91
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:91
struct Latch * MyLatch
Definition: globals.c:52
Definition: c.h:487
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:113
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
Datum pg_get_keywords(PG_FUNCTION_ARGS)
Definition: misc.c:562
NameData * Name
Definition: c.h:545
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2839
Definition: proc.h:95
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
#define SIGNAL_BACKEND_ERROR
Definition: misc.c:216
char * location
Definition: misc.c:368
#define WL_LATCH_SET
Definition: latch.h:124
int16 AttrNumber
Definition: attnum.h:21
#define _(x)
Definition: elog.c:84
#define ARR_NULLBITMAP(a)
Definition: array.h:285
DIR * dirdesc
Definition: misc.c:369
#define PG_RETURN_NULL()
Definition: fmgr.h:305
#define PG_RETURN_NAME(x)
Definition: fmgr.h:323
int FreeDir(DIR *dir)
Definition: fd.c:2714
Datum pg_column_is_updatable(PG_FUNCTION_ARGS)
Definition: misc.c:691
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:317
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295