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