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