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-2020, 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 <dirent.h>
19 #include <fcntl.h>
20 #include <math.h>
21 #include <unistd.h>
22 
23 #include "access/sysattr.h"
24 #include "access/table.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 "parser/scansup.h"
34 #include "pgstat.h"
35 #include "postmaster/syslogger.h"
36 #include "rewrite/rewriteHandler.h"
37 #include "storage/fd.h"
38 #include "tcop/tcopprot.h"
39 #include "utils/builtins.h"
40 #include "utils/lsyscache.h"
41 #include "utils/ruleutils.h"
42 #include "utils/timestamp.h"
43 
44 /*
45  * Common subroutine for num_nulls() and num_nonnulls().
46  * Returns true if successful, false if function should return NULL.
47  * If successful, total argument count and number of nulls are
48  * returned into *nargs and *nulls.
49  */
50 static bool
52  int32 *nargs, int32 *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 }
131 
132 /*
133  * num_nulls()
134  * Count the number of NULL arguments
135  */
136 Datum
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 }
147 
148 /*
149  * num_nonnulls()
150  * Count the number of non-NULL arguments
151  */
152 Datum
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 }
163 
164 
165 /*
166  * current_database()
167  * Expose the current database to the user
168  */
169 Datum
171 {
172  Name db;
173 
174  db = (Name) palloc(NAMEDATALEN);
175 
177  PG_RETURN_NAME(db);
178 }
179 
180 
181 /*
182  * current_query()
183  * Expose the current query to the user (useful in stored procedures)
184  * We might want to use ActivePortal->sourceText someday.
185  */
186 Datum
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 }
195 
196 /* Function to find out which databases make use of a tablespace */
197 
198 Datum
200 {
201  Oid tablespaceOid = PG_GETARG_OID(0);
202  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
203  bool randomAccess;
204  TupleDesc tupdesc;
205  Tuplestorestate *tupstore;
206  char *location;
207  DIR *dirdesc;
208  struct dirent *de;
209  MemoryContext oldcontext;
210 
211  /* check to see if caller supports us returning a tuplestore */
212  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
213  ereport(ERROR,
214  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
215  errmsg("set-valued function called in context that cannot accept a set")));
216  if (!(rsinfo->allowedModes & SFRM_Materialize))
217  ereport(ERROR,
218  (errcode(ERRCODE_SYNTAX_ERROR),
219  errmsg("materialize mode required, but it is not allowed in this context")));
220 
221  /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
223 
224  tupdesc = CreateTemplateTupleDesc(1);
225  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_tablespace_databases",
226  OIDOID, -1, 0);
227 
228  randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;
229  tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
230 
231  rsinfo->returnMode = SFRM_Materialize;
232  rsinfo->setResult = tupstore;
233  rsinfo->setDesc = tupdesc;
234 
235  MemoryContextSwitchTo(oldcontext);
236 
237  if (tablespaceOid == GLOBALTABLESPACE_OID)
238  {
240  (errmsg("global tablespace never has databases")));
241  /* return empty tuplestore */
242  return (Datum) 0;
243  }
244 
245  if (tablespaceOid == DEFAULTTABLESPACE_OID)
246  location = psprintf("base");
247  else
248  location = psprintf("pg_tblspc/%u/%s", tablespaceOid,
250 
251  dirdesc = AllocateDir(location);
252 
253  if (!dirdesc)
254  {
255  /* the only expected error is ENOENT */
256  if (errno != ENOENT)
257  ereport(ERROR,
259  errmsg("could not open directory \"%s\": %m",
260  location)));
262  (errmsg("%u is not a tablespace OID", tablespaceOid)));
263  /* return empty tuplestore */
264  return (Datum) 0;
265  }
266 
267  while ((de = ReadDir(dirdesc, location)) != NULL)
268  {
269  Oid datOid = atooid(de->d_name);
270  char *subdir;
271  bool isempty;
272  Datum values[1];
273  bool nulls[1];
274 
275  /* this test skips . and .., but is awfully weak */
276  if (!datOid)
277  continue;
278 
279  /* if database subdir is empty, don't report tablespace as used */
280 
281  subdir = psprintf("%s/%s", location, de->d_name);
282  isempty = directory_is_empty(subdir);
283  pfree(subdir);
284 
285  if (isempty)
286  continue; /* indeed, nothing in it */
287 
288  values[0] = ObjectIdGetDatum(datOid);
289  nulls[0] = false;
290 
291  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
292  }
293 
294  FreeDir(dirdesc);
295  return (Datum) 0;
296 }
297 
298 
299 /*
300  * pg_tablespace_location - get location for a tablespace
301  */
302 Datum
304 {
305  Oid tablespaceOid = PG_GETARG_OID(0);
306  char sourcepath[MAXPGPATH];
307  char targetpath[MAXPGPATH];
308  int rllen;
309 
310  /*
311  * It's useful to apply this function to pg_class.reltablespace, wherein
312  * zero means "the database's default tablespace". So, rather than
313  * throwing an error for zero, we choose to assume that's what is meant.
314  */
315  if (tablespaceOid == InvalidOid)
316  tablespaceOid = MyDatabaseTableSpace;
317 
318  /*
319  * Return empty string for the cluster's default tablespaces
320  */
321  if (tablespaceOid == DEFAULTTABLESPACE_OID ||
322  tablespaceOid == GLOBALTABLESPACE_OID)
324 
325 #if defined(HAVE_READLINK) || defined(WIN32)
326 
327  /*
328  * Find the location of the tablespace by reading the symbolic link that
329  * is in pg_tblspc/<oid>.
330  */
331  snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
332 
333  rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
334  if (rllen < 0)
335  ereport(ERROR,
337  errmsg("could not read symbolic link \"%s\": %m",
338  sourcepath)));
339  if (rllen >= sizeof(targetpath))
340  ereport(ERROR,
341  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
342  errmsg("symbolic link \"%s\" target is too long",
343  sourcepath)));
344  targetpath[rllen] = '\0';
345 
346  PG_RETURN_TEXT_P(cstring_to_text(targetpath));
347 #else
348  ereport(ERROR,
349  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
350  errmsg("tablespaces are not supported on this platform")));
351  PG_RETURN_NULL();
352 #endif
353 }
354 
355 /*
356  * pg_sleep - delay for N seconds
357  */
358 Datum
360 {
361  float8 secs = PG_GETARG_FLOAT8(0);
362  float8 endtime;
363 
364  /*
365  * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
366  * important signal (such as SIGALRM or SIGINT) arrives. Because
367  * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
368  * might ask for more than that, we sleep for at most 10 minutes and then
369  * loop.
370  *
371  * By computing the intended stop time initially, we avoid accumulation of
372  * extra delay across multiple sleeps. This also ensures we won't delay
373  * less than the specified time when WaitLatch is terminated early by a
374  * non-query-canceling signal such as SIGHUP.
375  */
376 #define GetNowFloat() ((float8) GetCurrentTimestamp() / 1000000.0)
377 
378  endtime = GetNowFloat() + secs;
379 
380  for (;;)
381  {
382  float8 delay;
383  long delay_ms;
384 
386 
387  delay = endtime - GetNowFloat();
388  if (delay >= 600.0)
389  delay_ms = 600000;
390  else if (delay > 0.0)
391  delay_ms = (long) ceil(delay * 1000.0);
392  else
393  break;
394 
395  (void) WaitLatch(MyLatch,
397  delay_ms,
400  }
401 
402  PG_RETURN_VOID();
403 }
404 
405 /* Function to return the list of grammar keywords */
406 Datum
408 {
409  FuncCallContext *funcctx;
410 
411  if (SRF_IS_FIRSTCALL())
412  {
413  MemoryContext oldcontext;
414  TupleDesc tupdesc;
415 
416  funcctx = SRF_FIRSTCALL_INIT();
417  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
418 
419  tupdesc = CreateTemplateTupleDesc(5);
420  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
421  TEXTOID, -1, 0);
422  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
423  CHAROID, -1, 0);
424  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "barelabel",
425  BOOLOID, -1, 0);
426  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "catdesc",
427  TEXTOID, -1, 0);
428  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "baredesc",
429  TEXTOID, -1, 0);
430 
431  funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
432 
433  MemoryContextSwitchTo(oldcontext);
434  }
435 
436  funcctx = SRF_PERCALL_SETUP();
437 
438  if (funcctx->call_cntr < ScanKeywords.num_keywords)
439  {
440  char *values[5];
441  HeapTuple tuple;
442 
443  /* cast-away-const is ugly but alternatives aren't much better */
444  values[0] = unconstify(char *,
445  GetScanKeyword(funcctx->call_cntr,
446  &ScanKeywords));
447 
448  switch (ScanKeywordCategories[funcctx->call_cntr])
449  {
450  case UNRESERVED_KEYWORD:
451  values[1] = "U";
452  values[3] = _("unreserved");
453  break;
454  case COL_NAME_KEYWORD:
455  values[1] = "C";
456  values[3] = _("unreserved (cannot be function or type name)");
457  break;
459  values[1] = "T";
460  values[3] = _("reserved (can be function or type name)");
461  break;
462  case RESERVED_KEYWORD:
463  values[1] = "R";
464  values[3] = _("reserved");
465  break;
466  default: /* shouldn't be possible */
467  values[1] = NULL;
468  values[3] = NULL;
469  break;
470  }
471 
472  if (ScanKeywordBareLabel[funcctx->call_cntr])
473  {
474  values[2] = "true";
475  values[4] = _("can be bare label");
476  }
477  else
478  {
479  values[2] = "false";
480  values[4] = _("requires AS");
481  }
482 
483  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
484 
485  SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
486  }
487 
488  SRF_RETURN_DONE(funcctx);
489 }
490 
491 
492 /*
493  * Return the type of the argument.
494  */
495 Datum
497 {
498  PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
499 }
500 
501 
502 /*
503  * Implementation of the COLLATE FOR expression; returns the collation
504  * of the argument.
505  */
506 Datum
508 {
509  Oid typeid;
510  Oid collid;
511 
512  typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
513  if (!typeid)
514  PG_RETURN_NULL();
515  if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
516  ereport(ERROR,
517  (errcode(ERRCODE_DATATYPE_MISMATCH),
518  errmsg("collations are not supported by type %s",
519  format_type_be(typeid))));
520 
521  collid = PG_GET_COLLATION();
522  if (!collid)
523  PG_RETURN_NULL();
525 }
526 
527 
528 /*
529  * pg_relation_is_updatable - determine which update events the specified
530  * relation supports.
531  *
532  * This relies on relation_is_updatable() in rewriteHandler.c, which see
533  * for additional information.
534  */
535 Datum
537 {
538  Oid reloid = PG_GETARG_OID(0);
539  bool include_triggers = PG_GETARG_BOOL(1);
540 
541  PG_RETURN_INT32(relation_is_updatable(reloid, NIL, include_triggers, NULL));
542 }
543 
544 /*
545  * pg_column_is_updatable - determine whether a column is updatable
546  *
547  * This function encapsulates the decision about just what
548  * information_schema.columns.is_updatable actually means. It's not clear
549  * whether deletability of the column's relation should be required, so
550  * we want that decision in C code where we could change it without initdb.
551  */
552 Datum
554 {
555  Oid reloid = PG_GETARG_OID(0);
558  bool include_triggers = PG_GETARG_BOOL(2);
559  int events;
560 
561  /* System columns are never updatable */
562  if (attnum <= 0)
563  PG_RETURN_BOOL(false);
564 
565  events = relation_is_updatable(reloid, NIL, include_triggers,
566  bms_make_singleton(col));
567 
568  /* We require both updatability and deletability of the relation */
569 #define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
570 
571  PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
572 }
573 
574 
575 /*
576  * Is character a valid identifier start?
577  * Must match scan.l's {ident_start} character class.
578  */
579 static bool
580 is_ident_start(unsigned char c)
581 {
582  /* Underscores and ASCII letters are OK */
583  if (c == '_')
584  return true;
585  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
586  return true;
587  /* Any high-bit-set character is OK (might be part of a multibyte char) */
588  if (IS_HIGHBIT_SET(c))
589  return true;
590  return false;
591 }
592 
593 /*
594  * Is character a valid identifier continuation?
595  * Must match scan.l's {ident_cont} character class.
596  */
597 static bool
598 is_ident_cont(unsigned char c)
599 {
600  /* Can be digit or dollar sign ... */
601  if ((c >= '0' && c <= '9') || c == '$')
602  return true;
603  /* ... or an identifier start character */
604  return is_ident_start(c);
605 }
606 
607 /*
608  * parse_ident - parse a SQL qualified identifier into separate identifiers.
609  * When strict mode is active (second parameter), then any chars after
610  * the last identifier are disallowed.
611  */
612 Datum
614 {
615  text *qualname = PG_GETARG_TEXT_PP(0);
616  bool strict = PG_GETARG_BOOL(1);
617  char *qualname_str = text_to_cstring(qualname);
618  ArrayBuildState *astate = NULL;
619  char *nextp;
620  bool after_dot = false;
621 
622  /*
623  * The code below scribbles on qualname_str in some cases, so we should
624  * reconvert qualname if we need to show the original string in error
625  * messages.
626  */
627  nextp = qualname_str;
628 
629  /* skip leading whitespace */
630  while (scanner_isspace(*nextp))
631  nextp++;
632 
633  for (;;)
634  {
635  char *curname;
636  bool missing_ident = true;
637 
638  if (*nextp == '"')
639  {
640  char *endp;
641 
642  curname = nextp + 1;
643  for (;;)
644  {
645  endp = strchr(nextp + 1, '"');
646  if (endp == NULL)
647  ereport(ERROR,
648  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
649  errmsg("string is not a valid identifier: \"%s\"",
650  text_to_cstring(qualname)),
651  errdetail("String has unclosed double quotes.")));
652  if (endp[1] != '"')
653  break;
654  memmove(endp, endp + 1, strlen(endp));
655  nextp = endp;
656  }
657  nextp = endp + 1;
658  *endp = '\0';
659 
660  if (endp - curname == 0)
661  ereport(ERROR,
662  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
663  errmsg("string is not a valid identifier: \"%s\"",
664  text_to_cstring(qualname)),
665  errdetail("Quoted identifier must not be empty.")));
666 
667  astate = accumArrayResult(astate, CStringGetTextDatum(curname),
668  false, TEXTOID, CurrentMemoryContext);
669  missing_ident = false;
670  }
671  else if (is_ident_start((unsigned char) *nextp))
672  {
673  char *downname;
674  int len;
675  text *part;
676 
677  curname = nextp++;
678  while (is_ident_cont((unsigned char) *nextp))
679  nextp++;
680 
681  len = nextp - curname;
682 
683  /*
684  * We don't implicitly truncate identifiers. This is useful for
685  * allowing the user to check for specific parts of the identifier
686  * being too long. It's easy enough for the user to get the
687  * truncated names by casting our output to name[].
688  */
689  downname = downcase_identifier(curname, len, false, false);
690  part = cstring_to_text_with_len(downname, len);
691  astate = accumArrayResult(astate, PointerGetDatum(part), false,
692  TEXTOID, CurrentMemoryContext);
693  missing_ident = false;
694  }
695 
696  if (missing_ident)
697  {
698  /* Different error messages based on where we failed. */
699  if (*nextp == '.')
700  ereport(ERROR,
701  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
702  errmsg("string is not a valid identifier: \"%s\"",
703  text_to_cstring(qualname)),
704  errdetail("No valid identifier before \".\".")));
705  else if (after_dot)
706  ereport(ERROR,
707  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
708  errmsg("string is not a valid identifier: \"%s\"",
709  text_to_cstring(qualname)),
710  errdetail("No valid identifier after \".\".")));
711  else
712  ereport(ERROR,
713  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
714  errmsg("string is not a valid identifier: \"%s\"",
715  text_to_cstring(qualname))));
716  }
717 
718  while (scanner_isspace(*nextp))
719  nextp++;
720 
721  if (*nextp == '.')
722  {
723  after_dot = true;
724  nextp++;
725  while (scanner_isspace(*nextp))
726  nextp++;
727  }
728  else if (*nextp == '\0')
729  {
730  break;
731  }
732  else
733  {
734  if (strict)
735  ereport(ERROR,
736  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
737  errmsg("string is not a valid identifier: \"%s\"",
738  text_to_cstring(qualname))));
739  break;
740  }
741  }
742 
744 }
745 
746 /*
747  * pg_current_logfile
748  *
749  * Report current log file used by log collector by scanning current_logfiles.
750  */
751 Datum
753 {
754  FILE *fd;
755  char lbuffer[MAXPGPATH];
756  char *logfmt;
757 
758  /* The log format parameter is optional */
759  if (PG_NARGS() == 0 || PG_ARGISNULL(0))
760  logfmt = NULL;
761  else
762  {
763  logfmt = text_to_cstring(PG_GETARG_TEXT_PP(0));
764 
765  if (strcmp(logfmt, "stderr") != 0 && strcmp(logfmt, "csvlog") != 0)
766  ereport(ERROR,
767  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
768  errmsg("log format \"%s\" is not supported", logfmt),
769  errhint("The supported log formats are \"stderr\" and \"csvlog\".")));
770  }
771 
773  if (fd == NULL)
774  {
775  if (errno != ENOENT)
776  ereport(ERROR,
778  errmsg("could not read file \"%s\": %m",
780  PG_RETURN_NULL();
781  }
782 
783 #ifdef WIN32
784  /* syslogger.c writes CRLF line endings on Windows */
785  _setmode(_fileno(fd), _O_TEXT);
786 #endif
787 
788  /*
789  * Read the file to gather current log filename(s) registered by the
790  * syslogger.
791  */
792  while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
793  {
794  char *log_format;
795  char *log_filepath;
796  char *nlpos;
797 
798  /* Extract log format and log file path from the line. */
799  log_format = lbuffer;
800  log_filepath = strchr(lbuffer, ' ');
801  if (log_filepath == NULL)
802  {
803  /* Uh oh. No space found, so file content is corrupted. */
804  elog(ERROR,
805  "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
806  break;
807  }
808 
809  *log_filepath = '\0';
810  log_filepath++;
811  nlpos = strchr(log_filepath, '\n');
812  if (nlpos == NULL)
813  {
814  /* Uh oh. No newline found, so file content is corrupted. */
815  elog(ERROR,
816  "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
817  break;
818  }
819  *nlpos = '\0';
820 
821  if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
822  {
823  FreeFile(fd);
824  PG_RETURN_TEXT_P(cstring_to_text(log_filepath));
825  }
826  }
827 
828  /* Close the current log filename file. */
829  FreeFile(fd);
830 
831  PG_RETURN_NULL();
832 }
833 
834 /*
835  * Report current log file used by log collector (1 argument version)
836  *
837  * note: this wrapper is necessary to pass the sanity check in opr_sanity,
838  * which checks that all built-in functions that share the implementing C
839  * function take the same number of arguments
840  */
841 Datum
843 {
844  return pg_current_logfile(fcinfo);
845 }
846 
847 /*
848  * SQL wrapper around RelationGetReplicaIndex().
849  */
850 Datum
852 {
853  Oid reloid = PG_GETARG_OID(0);
854  Oid idxoid;
855  Relation rel;
856 
857  rel = table_open(reloid, AccessShareLock);
858  idxoid = RelationGetReplicaIndex(rel);
860 
861  if (OidIsValid(idxoid))
862  PG_RETURN_OID(idxoid);
863  else
864  PG_RETURN_NULL();
865 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
uint64 call_cntr
Definition: funcapi.h:65
#define NIL
Definition: pg_list.h:65
static bool is_ident_start(unsigned char c)
Definition: misc.c:580
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
Datum pg_get_replica_identity_index(PG_FUNCTION_ARGS)
Definition: misc.c:851
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
int errhint(const char *fmt,...)
Definition: elog.c:1149
Datum pg_relation_is_updatable(PG_FUNCTION_ARGS)
Definition: misc.c:536
Datum parse_ident(PG_FUNCTION_ARGS)
Definition: misc.c:613
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4724
#define WL_TIMEOUT
Definition: latch.h:127
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition: misc.c:51
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:294
#define PointerGetDatum(X)
Definition: postgres.h:556
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
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:354
#define AccessShareLock
Definition: lockdefs.h:36
Datum pg_collation_for(PG_FUNCTION_ARGS)
Definition: misc.c:507
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1938
int errcode(int sqlerrcode)
Definition: elog.c:691
#define LOG_METAINFO_DATAFILE
Definition: syslogger.h:95
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
bool directory_is_empty(const char *path)
Definition: tablespace.c:846
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:29
#define UNRESERVED_KEYWORD
Definition: keywords.h:20
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
unsigned int Oid
Definition: postgres_ext.h:31
Definition: dirent.h:9
#define OidIsValid(objectId)
Definition: c.h:706
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:298
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_GET_COLLATION()
Definition: fmgr.h:198
void ResetLatch(Latch *latch)
Definition: latch.c:588
Datum pg_typeof(PG_FUNCTION_ARGS)
Definition: misc.c:496
char * generate_collation_name(Oid collid)
Definition: ruleutils.c:11446
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition: kwlookup.h:39
signed int int32
Definition: c.h:417
Oid MyDatabaseTableSpace
Definition: globals.c:87
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:390
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:2116
Datum current_database(PG_FUNCTION_ARGS)
Definition: misc.c:170
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
PGDLLIMPORT const ScanKeywordList ScanKeywords
Datum current_query(PG_FUNCTION_ARGS)
Definition: misc.c:187
#define NAMEDATALEN
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:300
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define GetNowFloat()
void pfree(void *pointer)
Definition: mcxt.c:1057
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition: misc.c:752
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1152
Datum pg_tablespace_location(PG_FUNCTION_ARGS)
Definition: misc.c:303
Definition: dirent.c:25
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:553
Datum pg_num_nulls(PG_FUNCTION_ARGS)
Definition: misc.c:137
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1804
#define ARR_DIMS(a)
Definition: array.h:282
#define MAXPGPATH
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
Definition: c.h:671
#define TYPE_FUNC_NAME_KEYWORD
Definition: keywords.h:22
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * c
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:186
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:200
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define readlink(path, buf, size)
Definition: win32_port.h:228
AttInMetadata * attinmeta
Definition: funcapi.h:91
int errdetail(const char *fmt,...)
Definition: elog.c:1035
int errcode_for_file_access(void)
Definition: elog.c:714
const bool ScanKeywordBareLabel[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:42
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2349
Datum pg_current_logfile_1arg(PG_FUNCTION_ARGS)
Definition: misc.c:842
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2610
Datum pg_sleep(PG_FUNCTION_ARGS)
Definition: misc.c:359
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
#define atooid(x)
Definition: postgres_ext.h:42
Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
Definition: misc.c:199
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5144
int relation_is_updatable(Oid reloid, List *outer_reloids, bool include_triggers, Bitmapset *include_cols)
#define WARNING
Definition: elog.h:40
const char * debug_query_string
Definition: postgres.c:88
#define unconstify(underlying_type, expr)
Definition: c.h:1239
Datum pg_num_nonnulls(PG_FUNCTION_ARGS)
Definition: misc.c:153
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
uint8 bits8
Definition: c.h:436
int num_keywords
Definition: kwlookup.h:30
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
FmgrInfo * flinfo
Definition: fmgr.h:87
Oid MyDatabaseId
Definition: globals.c:85
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2067
bool scanner_isspace(char ch)
Definition: scansup.c:117
#define PG_GETARG_INT16(n)
Definition: fmgr.h:271
int work_mem
Definition: globals.c:121
#define REQ_EVENTS
#define RESERVED_KEYWORD
Definition: keywords.h:23
#define InvalidOid
Definition: postgres_ext.h:36
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition: scansup.c:46
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:155
int allowedModes
Definition: execnodes.h:304
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
SetFunctionReturnMode returnMode
Definition: execnodes.h:306
text * cstring_to_text(const char *s)
Definition: varlena.c:188
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:800
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2676
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
static bool is_ident_cont(unsigned char c)
Definition: misc.c:598
#define PG_NARGS()
Definition: fmgr.h:203
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:232
#define ARR_NDIM(a)
Definition: array.h:278
#define COL_NAME_KEYWORD
Definition: keywords.h:21
Tuplestorestate * setResult
Definition: execnodes.h:309
int FreeFile(FILE *file)
Definition: fd.c:2548
static Datum values[MAXATTR]
Definition: bootstrap.c:165
char * text_to_cstring(const text *t)
Definition: varlena.c:221
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5080
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2714
ExprContext * econtext
Definition: execnodes.h:302
TupleDesc setDesc
Definition: execnodes.h:310
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
#define elog(elevel,...)
Definition: elog.h:228
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:86
struct Latch * MyLatch
Definition: globals.c:54
Definition: c.h:617
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
Datum pg_get_keywords(PG_FUNCTION_ARGS)
Definition: misc.c:407
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
NameData * Name
Definition: c.h:675
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2963
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define snprintf
Definition: port.h:215
#define WL_LATCH_SET
Definition: latch.h:124
int16 AttrNumber
Definition: attnum.h:21
#define _(x)
Definition: elog.c:88
#define ARR_NULLBITMAP(a)
Definition: array.h:288
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_NAME(x)
Definition: fmgr.h:363
int FreeDir(DIR *dir)
Definition: fd.c:2728
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129
Datum pg_column_is_updatable(PG_FUNCTION_ARGS)
Definition: misc.c:553
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:318
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:296