PostgreSQL Source Code git master
Loading...
Searching...
No Matches
misc.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * misc.c
4 *
5 *
6 * Portions Copyright (c) 1996-2026, 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 <sys/stat.h>
19#include <dirent.h>
20#include <fcntl.h>
21#include <math.h>
22#include <unistd.h>
23
24#include "access/htup_details.h"
25#include "access/sysattr.h"
26#include "access/table.h"
28#include "catalog/pg_type.h"
29#include "catalog/system_fk_info.h"
30#include "commands/tablespace.h"
31#include "common/keywords.h"
32#include "funcapi.h"
33#include "miscadmin.h"
34#include "nodes/miscnodes.h"
35#include "parser/parse_type.h"
36#include "parser/scansup.h"
37#include "pgstat.h"
40#include "storage/fd.h"
41#include "storage/latch.h"
42#include "tcop/tcopprot.h"
43#include "utils/builtins.h"
44#include "utils/fmgroids.h"
45#include "utils/lsyscache.h"
46#include "utils/ruleutils.h"
47#include "utils/syscache.h"
48#include "utils/timestamp.h"
49#include "utils/wait_event.h"
50
51
52/*
53 * structure to cache metadata needed in pg_input_is_valid_common
54 */
64
67 ErrorSaveContext *escontext);
68
69
70/*
71 * Common subroutine for num_nulls() and num_nonnulls().
72 * Returns true if successful, false if function should return NULL.
73 * If successful, total argument count and number of nulls are
74 * returned into *nargs and *nulls.
75 */
76static bool
78 int32 *nargs, int32 *nulls)
79{
80 int32 count = 0;
81 int i;
82
83 /* Did we get a VARIADIC array argument, or separate arguments? */
84 if (get_fn_expr_variadic(fcinfo->flinfo))
85 {
86 ArrayType *arr;
87 int ndims,
88 nitems,
89 *dims;
90 bits8 *bitmap;
91
92 Assert(PG_NARGS() == 1);
93
94 /*
95 * If we get a null as VARIADIC array argument, we can't say anything
96 * useful about the number of elements, so return NULL. This behavior
97 * is consistent with other variadic functions - see concat_internal.
98 */
99 if (PG_ARGISNULL(0))
100 return false;
101
102 /*
103 * Non-null argument had better be an array. We assume that any call
104 * context that could let get_fn_expr_variadic return true will have
105 * checked that a VARIADIC-labeled parameter actually is an array. So
106 * it should be okay to just Assert that it's an array rather than
107 * doing a full-fledged error check.
108 */
110
111 /* OK, safe to fetch the array value */
112 arr = PG_GETARG_ARRAYTYPE_P(0);
113
114 /* Count the array elements */
115 ndims = ARR_NDIM(arr);
116 dims = ARR_DIMS(arr);
117 nitems = ArrayGetNItems(ndims, dims);
118
119 /* Count those that are NULL */
120 bitmap = ARR_NULLBITMAP(arr);
121 if (bitmap)
122 {
123 int bitmask = 1;
124
125 for (i = 0; i < nitems; i++)
126 {
127 if ((*bitmap & bitmask) == 0)
128 count++;
129
130 bitmask <<= 1;
131 if (bitmask == 0x100)
132 {
133 bitmap++;
134 bitmask = 1;
135 }
136 }
137 }
138
139 *nargs = nitems;
140 *nulls = count;
141 }
142 else
143 {
144 /* Separate arguments, so just count 'em */
145 for (i = 0; i < PG_NARGS(); i++)
146 {
147 if (PG_ARGISNULL(i))
148 count++;
149 }
150
151 *nargs = PG_NARGS();
152 *nulls = count;
153 }
154
155 return true;
156}
157
158/*
159 * num_nulls()
160 * Count the number of NULL arguments
161 */
162Datum
164{
165 int32 nargs,
166 nulls;
167
168 if (!count_nulls(fcinfo, &nargs, &nulls))
170
171 PG_RETURN_INT32(nulls);
172}
173
174/*
175 * num_nonnulls()
176 * Count the number of non-NULL arguments
177 */
178Datum
180{
181 int32 nargs,
182 nulls;
183
184 if (!count_nulls(fcinfo, &nargs, &nulls))
186
187 PG_RETURN_INT32(nargs - nulls);
188}
189
190/*
191 * error_on_null()
192 * Check if the input is the NULL value
193 */
194Datum
196{
197 if (PG_ARGISNULL(0))
200 errmsg("null value not allowed")));
201
203}
204
205/*
206 * current_database()
207 * Expose the current database to the user
208 */
209Datum
219
220
221/*
222 * current_query()
223 * Expose the current query to the user (useful in stored procedures)
224 * We might want to use ActivePortal->sourceText someday.
225 */
226Datum
228{
229 /* there is no easy way to access the more concise 'query_string' */
232 else
234}
235
236/* Function to find out which databases make use of a tablespace */
237
238Datum
240{
241 Oid tablespaceOid = PG_GETARG_OID(0);
242 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
243 char *location;
244 DIR *dirdesc;
245 struct dirent *de;
246
248
249 if (tablespaceOid == GLOBALTABLESPACE_OID)
250 {
252 (errmsg("global tablespace never has databases")));
253 /* return empty tuplestore */
254 return (Datum) 0;
255 }
256
257 if (tablespaceOid == DEFAULTTABLESPACE_OID)
258 location = "base";
259 else
260 location = psprintf("%s/%u/%s", PG_TBLSPC_DIR, tablespaceOid,
262
263 dirdesc = AllocateDir(location);
264
265 if (!dirdesc)
266 {
267 /* the only expected error is ENOENT */
268 if (errno != ENOENT)
271 errmsg("could not open directory \"%s\": %m",
272 location)));
274 (errmsg("%u is not a tablespace OID", tablespaceOid)));
275 /* return empty tuplestore */
276 return (Datum) 0;
277 }
278
279 while ((de = ReadDir(dirdesc, location)) != NULL)
280 {
281 Oid datOid = atooid(de->d_name);
282 char *subdir;
283 bool isempty;
284 Datum values[1];
285 bool nulls[1];
286
287 /* this test skips . and .., but is awfully weak */
288 if (!datOid)
289 continue;
290
291 /* if database subdir is empty, don't report tablespace as used */
292
293 subdir = psprintf("%s/%s", location, de->d_name);
295 pfree(subdir);
296
297 if (isempty)
298 continue; /* indeed, nothing in it */
299
301 nulls[0] = false;
302
303 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
304 values, nulls);
305 }
306
307 FreeDir(dirdesc);
308 return (Datum) 0;
309}
310
311
312/*
313 * pg_tablespace_location - get location for a tablespace
314 */
315Datum
317{
318 Oid tablespaceOid = PG_GETARG_OID(0);
319 char *tablespaceLoc;
320
321 /* Get LOCATION string from its OID */
322 tablespaceLoc = get_tablespace_location(tablespaceOid);
323
325}
326
327/*
328 * pg_sleep - delay for N seconds
329 */
330Datum
332{
334 int64 usecs;
336
337 /*
338 * Convert the delay to int64 microseconds, rounding up any fraction, and
339 * silently limiting it to PG_INT64_MAX/2 microseconds (about 150K years)
340 * to ensure the computation of endtime won't overflow. Historically
341 * we've treated NaN as "no wait", not an error, so keep that behavior.
342 */
343 if (isnan(secs) || secs <= 0.0)
345 secs *= USECS_PER_SEC; /* we assume overflow will produce +Inf */
346 secs = ceil(secs); /* round up any fractional microsecond */
347 usecs = (int64) Min(secs, (float8) (PG_INT64_MAX / 2));
348
349 /*
350 * We sleep using WaitLatch, to ensure that we'll wake up promptly if an
351 * important signal (such as SIGALRM or SIGINT) arrives. Because
352 * WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
353 * might ask for more than that, we sleep for at most 10 minutes and then
354 * loop.
355 *
356 * By computing the intended stop time initially, we avoid accumulation of
357 * extra delay across multiple sleeps. This also ensures we won't delay
358 * less than the specified time when WaitLatch is terminated early by a
359 * non-query-canceling signal such as SIGHUP.
360 */
362
363 for (;;)
364 {
366 long delay_ms;
367
369
371 if (delay >= 600 * USECS_PER_SEC)
372 delay_ms = 600000;
373 else if (delay > 0)
374 delay_ms = (long) ((delay + 999) / 1000);
375 else
376 break;
377
380 delay_ms,
383 }
384
386}
387
388/* Function to return the list of grammar keywords */
389Datum
391{
393
394 if (SRF_IS_FIRSTCALL())
395 {
396 MemoryContext oldcontext;
397 TupleDesc tupdesc;
398
400 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
401
402 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
403 elog(ERROR, "return type must be a row type");
404 funcctx->tuple_desc = tupdesc;
405 funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
406
407 MemoryContextSwitchTo(oldcontext);
408 }
409
411
412 if (funcctx->call_cntr < ScanKeywords.num_keywords)
413 {
414 char *values[5];
415 HeapTuple tuple;
416
417 /* cast-away-const is ugly but alternatives aren't much better */
418 values[0] = unconstify(char *,
419 GetScanKeyword(funcctx->call_cntr,
420 &ScanKeywords));
421
422 switch (ScanKeywordCategories[funcctx->call_cntr])
423 {
425 values[1] = "U";
426 values[3] = _("unreserved");
427 break;
428 case COL_NAME_KEYWORD:
429 values[1] = "C";
430 values[3] = _("unreserved (cannot be function or type name)");
431 break;
433 values[1] = "T";
434 values[3] = _("reserved (can be function or type name)");
435 break;
436 case RESERVED_KEYWORD:
437 values[1] = "R";
438 values[3] = _("reserved");
439 break;
440 default: /* shouldn't be possible */
441 values[1] = NULL;
442 values[3] = NULL;
443 break;
444 }
445
446 if (ScanKeywordBareLabel[funcctx->call_cntr])
447 {
448 values[2] = "true";
449 values[4] = _("can be bare label");
450 }
451 else
452 {
453 values[2] = "false";
454 values[4] = _("requires AS");
455 }
456
457 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
458
460 }
461
463}
464
465
466/* Function to return the list of catalog foreign key relationships */
467Datum
469{
472
473 if (SRF_IS_FIRSTCALL())
474 {
475 MemoryContext oldcontext;
476 TupleDesc tupdesc;
477
479 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
480
481 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
482 elog(ERROR, "return type must be a row type");
483 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
484
485 /*
486 * We use array_in to convert the C strings in sys_fk_relationships[]
487 * to text arrays. But we cannot use DirectFunctionCallN to call
488 * array_in, and it wouldn't be very efficient if we could. Fill an
489 * FmgrInfo to use for the call.
490 */
493 funcctx->user_fctx = arrayinp;
494
495 MemoryContextSwitchTo(oldcontext);
496 }
497
499 arrayinp = (FmgrInfo *) funcctx->user_fctx;
500
501 if (funcctx->call_cntr < lengthof(sys_fk_relationships))
502 {
504 Datum values[6];
505 bool nulls[6];
506 HeapTuple tuple;
507
508 memset(nulls, false, sizeof(nulls));
509
510 values[0] = ObjectIdGetDatum(fkrel->fk_table);
512 CStringGetDatum(fkrel->fk_columns),
514 Int32GetDatum(-1));
515 values[2] = ObjectIdGetDatum(fkrel->pk_table);
517 CStringGetDatum(fkrel->pk_columns),
519 Int32GetDatum(-1));
520 values[4] = BoolGetDatum(fkrel->is_array);
521 values[5] = BoolGetDatum(fkrel->is_opt);
522
523 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
524
526 }
527
529}
530
531
532/*
533 * Return the type of the argument.
534 */
535Datum
540
541
542/*
543 * Return the base type of the argument.
544 * If the given type is a domain, return its base type;
545 * otherwise return the type's own OID.
546 * Return NULL if the type OID doesn't exist or points to a
547 * non-existent base type.
548 *
549 * This is a SQL-callable version of getBaseType(). Unlike that function,
550 * we don't want to fail for a bogus type OID; this is helpful to keep race
551 * conditions from turning into query failures when scanning the catalogs.
552 * Hence we need our own implementation.
553 */
554Datum
556{
557 Oid typid = PG_GETARG_OID(0);
558
559 /*
560 * We loop to find the bottom base type in a stack of domains.
561 */
562 for (;;)
563 {
566
568 if (!HeapTupleIsValid(tup))
569 PG_RETURN_NULL(); /* return NULL for bogus OID */
571 if (typTup->typtype != TYPTYPE_DOMAIN)
572 {
573 /* Not a domain, so done */
575 break;
576 }
577
578 typid = typTup->typbasetype;
580 }
581
582 PG_RETURN_OID(typid);
583}
584
585
586/*
587 * Implementation of the COLLATE FOR expression; returns the collation
588 * of the argument.
589 */
590Datum
592{
593 Oid typeid;
594 Oid collid;
595
596 typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
597 if (!typeid)
599 if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
602 errmsg("collations are not supported by type %s",
603 format_type_be(typeid))));
604
606 if (!collid)
609}
610
611
612/*
613 * pg_relation_is_updatable - determine which update events the specified
614 * relation supports.
615 *
616 * This relies on relation_is_updatable() in rewriteHandler.c, which see
617 * for additional information.
618 */
619Datum
627
628/*
629 * pg_column_is_updatable - determine whether a column is updatable
630 *
631 * This function encapsulates the decision about just what
632 * information_schema.columns.is_updatable actually means. It's not clear
633 * whether deletability of the column's relation should be required, so
634 * we want that decision in C code where we could change it without initdb.
635 */
636Datum
638{
639 Oid reloid = PG_GETARG_OID(0);
643 int events;
644
645 /* System columns are never updatable */
646 if (attnum <= 0)
647 PG_RETURN_BOOL(false);
648
651
652 /* We require both updatability and deletability of the relation */
653#define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE))
654
655 PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
656}
657
658
659/*
660 * pg_input_is_valid - test whether string is valid input for datatype.
661 *
662 * Returns true if OK, false if not.
663 *
664 * This will only work usefully if the datatype's input function has been
665 * updated to return "soft" errors via errsave/ereturn.
666 */
667Datum
677
678/*
679 * pg_input_error_info - test whether string is valid input for datatype.
680 *
681 * Returns NULL if OK, else the primary message, detail message, hint message
682 * and sql error code from the error.
683 *
684 * This will only work usefully if the datatype's input function has been
685 * updated to return "soft" errors via errsave/ereturn.
686 */
687Datum
689{
693 TupleDesc tupdesc;
694 Datum values[4];
695 bool isnull[4];
696
697 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
698 elog(ERROR, "return type must be a row type");
699
700 /* Enable details_wanted */
701 escontext.details_wanted = true;
702
704 &escontext))
705 memset(isnull, true, sizeof(isnull));
706 else
707 {
708 char *sqlstate;
709
710 Assert(escontext.error_occurred);
711 Assert(escontext.error_data != NULL);
712 Assert(escontext.error_data->message != NULL);
713
714 memset(isnull, false, sizeof(isnull));
715
717
718 if (escontext.error_data->detail != NULL)
720 else
721 isnull[1] = true;
722
723 if (escontext.error_data->hint != NULL)
724 values[2] = CStringGetTextDatum(escontext.error_data->hint);
725 else
726 isnull[2] = true;
727
728 sqlstate = unpack_sql_state(escontext.error_data->sqlerrcode);
729 values[3] = CStringGetTextDatum(sqlstate);
730 }
731
732 return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
733}
734
735/* Common subroutine for the above */
736static bool
738 text *txt, text *typname,
739 ErrorSaveContext *escontext)
740{
741 char *str = text_to_cstring(txt);
744
745 /*
746 * We arrange to look up the needed I/O info just once per series of
747 * calls, assuming the data type doesn't change underneath us.
748 */
749 my_extra = (ValidIOData *) fcinfo->flinfo->fn_extra;
750 if (my_extra == NULL)
751 {
752 fcinfo->flinfo->fn_extra =
754 sizeof(ValidIOData));
755 my_extra = (ValidIOData *) fcinfo->flinfo->fn_extra;
756 my_extra->typoid = InvalidOid;
757 /* Detect whether typname argument is constant. */
758 my_extra->typname_constant = get_fn_expr_arg_stable(fcinfo->flinfo, 1);
759 }
760
761 /*
762 * If the typname argument is constant, we only need to parse it the first
763 * time through.
764 */
765 if (my_extra->typoid == InvalidOid || !my_extra->typname_constant)
766 {
768 Oid typoid;
769
770 /* Parse type-name argument to obtain type OID and encoded typmod. */
771 (void) parseTypeString(typnamestr, &typoid, &my_extra->typmod, NULL);
772
773 /* Update type-specific info if typoid changed. */
774 if (my_extra->typoid != typoid)
775 {
776 getTypeInputInfo(typoid,
777 &my_extra->typiofunc,
778 &my_extra->typioparam);
779 fmgr_info_cxt(my_extra->typiofunc, &my_extra->inputproc,
780 fcinfo->flinfo->fn_mcxt);
781 my_extra->typoid = typoid;
782 }
783 }
784
785 /* Now we can try to perform the conversion. */
786 return InputFunctionCallSafe(&my_extra->inputproc,
787 str,
788 my_extra->typioparam,
789 my_extra->typmod,
790 (Node *) escontext,
791 &converted);
792}
793
794
795/*
796 * Is character a valid identifier start?
797 * Must match scan.l's {ident_start} character class.
798 */
799static bool
800is_ident_start(unsigned char c)
801{
802 /* Underscores and ASCII letters are OK */
803 if (c == '_')
804 return true;
805 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
806 return true;
807 /* Any high-bit-set character is OK (might be part of a multibyte char) */
808 if (IS_HIGHBIT_SET(c))
809 return true;
810 return false;
811}
812
813/*
814 * Is character a valid identifier continuation?
815 * Must match scan.l's {ident_cont} character class.
816 */
817static bool
818is_ident_cont(unsigned char c)
819{
820 /* Can be digit or dollar sign ... */
821 if ((c >= '0' && c <= '9') || c == '$')
822 return true;
823 /* ... or an identifier start character */
824 return is_ident_start(c);
825}
826
827/*
828 * parse_ident - parse a SQL qualified identifier into separate identifiers.
829 * When strict mode is active (second parameter), then any chars after
830 * the last identifier are disallowed.
831 */
832Datum
834{
836 bool strict = PG_GETARG_BOOL(1);
838 ArrayBuildState *astate = NULL;
839 char *nextp;
840 bool after_dot = false;
841
842 /*
843 * The code below scribbles on qualname_str in some cases, so we should
844 * reconvert qualname if we need to show the original string in error
845 * messages.
846 */
848
849 /* skip leading whitespace */
850 while (scanner_isspace(*nextp))
851 nextp++;
852
853 for (;;)
854 {
855 char *curname;
856 bool missing_ident = true;
857
858 if (*nextp == '"')
859 {
860 char *endp;
861
862 curname = nextp + 1;
863 for (;;)
864 {
865 endp = strchr(nextp + 1, '"');
866 if (endp == NULL)
869 errmsg("string is not a valid identifier: \"%s\"",
871 errdetail("String has unclosed double quotes.")));
872 if (endp[1] != '"')
873 break;
874 memmove(endp, endp + 1, strlen(endp));
875 nextp = endp;
876 }
877 nextp = endp + 1;
878 *endp = '\0';
879
880 if (endp - curname == 0)
883 errmsg("string is not a valid identifier: \"%s\"",
885 errdetail("Quoted identifier must not be empty.")));
886
889 missing_ident = false;
890 }
891 else if (is_ident_start((unsigned char) *nextp))
892 {
893 char *downname;
894 int len;
895 text *part;
896
897 curname = nextp++;
898 while (is_ident_cont((unsigned char) *nextp))
899 nextp++;
900
901 len = nextp - curname;
902
903 /*
904 * We don't implicitly truncate identifiers. This is useful for
905 * allowing the user to check for specific parts of the identifier
906 * being too long. It's easy enough for the user to get the
907 * truncated names by casting our output to name[].
908 */
909 downname = downcase_identifier(curname, len, false, false);
911 astate = accumArrayResult(astate, PointerGetDatum(part), false,
913 missing_ident = false;
914 }
915
916 if (missing_ident)
917 {
918 /* Different error messages based on where we failed. */
919 if (*nextp == '.')
922 errmsg("string is not a valid identifier: \"%s\"",
924 errdetail("No valid identifier before \".\".")));
925 else if (after_dot)
928 errmsg("string is not a valid identifier: \"%s\"",
930 errdetail("No valid identifier after \".\".")));
931 else
934 errmsg("string is not a valid identifier: \"%s\"",
936 }
937
938 while (scanner_isspace(*nextp))
939 nextp++;
940
941 if (*nextp == '.')
942 {
943 after_dot = true;
944 nextp++;
945 while (scanner_isspace(*nextp))
946 nextp++;
947 }
948 else if (*nextp == '\0')
949 {
950 break;
951 }
952 else
953 {
954 if (strict)
957 errmsg("string is not a valid identifier: \"%s\"",
959 break;
960 }
961 }
962
964}
965
966/*
967 * pg_current_logfile
968 *
969 * Report current log file used by log collector by scanning current_logfiles.
970 */
971Datum
973{
974 FILE *fd;
975 char lbuffer[MAXPGPATH];
976 char *logfmt;
977
978 /* The log format parameter is optional */
979 if (PG_NARGS() == 0 || PG_ARGISNULL(0))
980 logfmt = NULL;
981 else
982 {
984
985 if (strcmp(logfmt, "stderr") != 0 &&
986 strcmp(logfmt, "csvlog") != 0 &&
987 strcmp(logfmt, "jsonlog") != 0)
990 errmsg("log format \"%s\" is not supported", logfmt),
991 errhint("The supported log formats are \"stderr\", \"csvlog\", and \"jsonlog\".")));
992 }
993
995 if (fd == NULL)
996 {
997 if (errno != ENOENT)
1000 errmsg("could not read file \"%s\": %m",
1003 }
1004
1005#ifdef WIN32
1006 /* syslogger.c writes CRLF line endings on Windows */
1008#endif
1009
1010 /*
1011 * Read the file to gather current log filename(s) registered by the
1012 * syslogger.
1013 */
1014 while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL)
1015 {
1016 char *log_format;
1017 char *log_filepath;
1018 char *nlpos;
1019
1020 /* Extract log format and log file path from the line. */
1022 log_filepath = strchr(lbuffer, ' ');
1023 if (log_filepath == NULL)
1024 {
1025 /* Uh oh. No space found, so file content is corrupted. */
1026 elog(ERROR,
1027 "missing space character in \"%s\"", LOG_METAINFO_DATAFILE);
1028 break;
1029 }
1030
1031 *log_filepath = '\0';
1032 log_filepath++;
1033 nlpos = strchr(log_filepath, '\n');
1034 if (nlpos == NULL)
1035 {
1036 /* Uh oh. No newline found, so file content is corrupted. */
1037 elog(ERROR,
1038 "missing newline character in \"%s\"", LOG_METAINFO_DATAFILE);
1039 break;
1040 }
1041 *nlpos = '\0';
1042
1043 if (logfmt == NULL || strcmp(logfmt, log_format) == 0)
1044 {
1045 FreeFile(fd);
1047 }
1048 }
1049
1050 /* Close the current log filename file. */
1051 FreeFile(fd);
1052
1054}
1055
1056/*
1057 * Report current log file used by log collector (1 argument version)
1058 *
1059 * note: this wrapper is necessary to pass the sanity check in opr_sanity,
1060 * which checks that all built-in functions that share the implementing C
1061 * function take the same number of arguments
1062 */
1063Datum
1068
1069/*
1070 * SQL wrapper around RelationGetReplicaIndex().
1071 */
1072Datum
1074{
1075 Oid reloid = PG_GETARG_OID(0);
1076 Oid idxoid;
1077 Relation rel;
1078
1079 rel = table_open(reloid, AccessShareLock);
1082
1083 if (OidIsValid(idxoid))
1085 else
1087}
1088
1089/*
1090 * Transition function for the ANY_VALUE aggregate
1091 */
1092Datum
#define ARR_NDIM(a)
Definition array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
#define ARR_NULLBITMAP(a)
Definition array.h:300
#define ARR_DIMS(a)
Definition array.h:294
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
int ArrayGetNItems(int ndim, const int *dims)
Definition arrayutils.c:57
int16 AttrNumber
Definition attnum.h:21
bool directory_is_empty(const char *path)
Definition tablespace.c:860
Datum pg_typeof(PG_FUNCTION_ARGS)
Definition misc.c:536
Datum parse_ident(PG_FUNCTION_ARGS)
Definition misc.c:833
static bool count_nulls(FunctionCallInfo fcinfo, int32 *nargs, int32 *nulls)
Definition misc.c:77
Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
Definition misc.c:239
static bool is_ident_cont(unsigned char c)
Definition misc.c:818
#define REQ_EVENTS
Datum current_query(PG_FUNCTION_ARGS)
Definition misc.c:227
Datum pg_get_catalog_foreign_keys(PG_FUNCTION_ARGS)
Definition misc.c:468
static bool pg_input_is_valid_common(FunctionCallInfo fcinfo, text *txt, text *typname, ErrorSaveContext *escontext)
Definition misc.c:737
Datum pg_input_error_info(PG_FUNCTION_ARGS)
Definition misc.c:688
Datum pg_input_is_valid(PG_FUNCTION_ARGS)
Definition misc.c:668
Datum any_value_transfn(PG_FUNCTION_ARGS)
Definition misc.c:1093
Datum pg_sleep(PG_FUNCTION_ARGS)
Definition misc.c:331
Datum pg_get_replica_identity_index(PG_FUNCTION_ARGS)
Definition misc.c:1073
Datum pg_current_logfile(PG_FUNCTION_ARGS)
Definition misc.c:972
Datum pg_get_keywords(PG_FUNCTION_ARGS)
Definition misc.c:390
static bool is_ident_start(unsigned char c)
Definition misc.c:800
Datum current_database(PG_FUNCTION_ARGS)
Definition misc.c:210
Datum pg_column_is_updatable(PG_FUNCTION_ARGS)
Definition misc.c:637
Datum pg_num_nulls(PG_FUNCTION_ARGS)
Definition misc.c:163
Datum pg_basetype(PG_FUNCTION_ARGS)
Definition misc.c:555
Datum pg_current_logfile_1arg(PG_FUNCTION_ARGS)
Definition misc.c:1064
Datum pg_tablespace_location(PG_FUNCTION_ARGS)
Definition misc.c:316
Datum pg_relation_is_updatable(PG_FUNCTION_ARGS)
Definition misc.c:620
Datum pg_collation_for(PG_FUNCTION_ARGS)
Definition misc.c:591
Datum pg_error_on_null(PG_FUNCTION_ARGS)
Definition misc.c:195
Datum pg_num_nonnulls(PG_FUNCTION_ARGS)
Definition misc.c:179
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1643
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
static Datum values[MAXATTR]
Definition bootstrap.c:187
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define unconstify(underlying_type, expr)
Definition c.h:1288
NameData * Name
Definition c.h:796
#define Min(x, y)
Definition c.h:1054
#define IS_HIGHBIT_SET(ch)
Definition c.h:1207
#define Assert(condition)
Definition c.h:906
int64_t int64
Definition c.h:576
double float8
Definition c.h:677
uint8 bits8
Definition c.h:586
int32_t int32
Definition c.h:575
#define PG_INT64_MAX
Definition c.h:639
#define lengthof(array)
Definition c.h:836
#define OidIsValid(objectId)
Definition c.h:821
Oid collid
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
Definition keywords.c:29
const bool ScanKeywordBareLabel[SCANKEYWORDS_NUM_KEYWORDS]
Definition keywords.c:42
int64 TimestampTz
Definition timestamp.h:39
#define USECS_PER_SEC
Definition timestamp.h:134
int errcode_for_file_access(void)
Definition elog.c:897
int errcode(int sqlerrcode)
Definition elog.c:874
char * unpack_sql_state(int sql_state)
Definition elog.c:3653
#define _(x)
Definition elog.c:95
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
int FreeDir(DIR *dir)
Definition fd.c:3009
int FreeFile(FILE *file)
Definition fd.c:2827
DIR * AllocateDir(const char *dirname)
Definition fd.c:2891
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition fd.c:2957
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
#define palloc_object(type)
Definition fe_memutils.h:74
bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1940
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:128
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition fmgr.c:138
bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
Definition fmgr.c:1585
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition fmgr.c:2009
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1875
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_NARGS()
Definition fmgr.h:203
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_RETURN_NAME(x)
Definition fmgr.h:365
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define PG_GET_COLLATION()
Definition fmgr.h:198
#define FunctionCall3(flinfo, arg1, arg2, arg3)
Definition fmgr.h:706
#define PG_RETURN_OID(x)
Definition fmgr.h:361
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_GETARG_INT16(n)
Definition fmgr.h:271
char * format_type_be(Oid type_oid)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition funcapi.c:76
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
#define MAT_SRF_USE_EXPECTED_DESC
Definition funcapi.h:296
struct Latch * MyLatch
Definition globals.c:63
Oid MyDatabaseId
Definition globals.c:94
const char * str
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define nitems(x)
Definition indent.h:31
int i
Definition isn.c:77
PGDLLIMPORT const ScanKeywordList ScanKeywords
#define COL_NAME_KEYWORD
Definition keywords.h:21
#define UNRESERVED_KEYWORD
Definition keywords.h:20
#define TYPE_FUNC_NAME_KEYWORD
Definition keywords.h:22
#define RESERVED_KEYWORD
Definition keywords.h:23
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition kwlookup.h:39
void ResetLatch(Latch *latch)
Definition latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition latch.c:172
#define AccessShareLock
Definition lockdefs.h:36
char * get_database_name(Oid dbid)
Definition lsyscache.c:1242
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition lsyscache.c:3026
bool type_is_collatable(Oid typid)
Definition lsyscache.c:3233
Oid get_base_element_type(Oid typid)
Definition lsyscache.c:2984
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
void namestrcpy(Name name, const char *str)
Definition name.c:233
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
bool parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, Node *escontext)
Definition parse_type.c:785
int16 attnum
#define NAMEDATALEN
#define MAXPGPATH
const void size_t len
#define NIL
Definition pg_list.h:68
char * get_tablespace_location(Oid tablespaceOid)
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265
NameData typname
Definition pg_type.h:43
const char * debug_query_string
Definition postgres.c:90
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define InvalidOid
unsigned int Oid
#define atooid(x)
char * c
static int fd(const char *x, int i)
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
Oid RelationGetReplicaIndex(Relation relation)
Definition relcache.c:5067
#define PG_TBLSPC_DIR
Definition relpath.h:41
#define TABLESPACE_VERSION_DIRECTORY
Definition relpath.h:33
int relation_is_updatable(Oid reloid, List *outer_reloids, bool include_triggers, Bitmapset *include_cols)
char * generate_collation_name(Oid collid)
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition scansup.c:47
bool scanner_isspace(char ch)
Definition scansup.c:105
Definition dirent.c:26
int sqlerrcode
Definition elog.h:431
char * detail
Definition elog.h:433
char * message
Definition elog.h:432
char * hint
Definition elog.h:435
ErrorData * error_data
Definition miscnodes.h:49
void * fn_extra
Definition fmgr.h:64
MemoryContext fn_mcxt
Definition fmgr.h:65
FmgrInfo * flinfo
Definition fmgr.h:87
Definition nodes.h:135
int32 typmod
Definition misc.c:58
Oid typoid
Definition misc.c:57
bool typname_constant
Definition misc.c:59
FmgrInfo inputproc
Definition misc.c:62
Oid typiofunc
Definition misc.c:60
Oid typioparam
Definition misc.c:61
Definition c.h:793
Definition c.h:739
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220
#define LOG_METAINFO_DATAFILE
Definition syslogger.h:102
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:784
text * cstring_to_text_with_len(const char *s, int len)
Definition varlena.c:194
text * cstring_to_text(const char *s)
Definition varlena.c:182
char * text_to_cstring(const text *t)
Definition varlena.c:215
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET