PostgreSQL Source Code git master
Loading...
Searching...
No Matches
ddlutils.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * ddlutils.c
4 * Utility functions for generating DDL statements
5 *
6 * This file contains the pg_get_*_ddl family of functions that generate
7 * DDL statements to recreate database objects such as roles, tablespaces,
8 * and databases, along with common infrastructure for option parsing and
9 * pretty-printing.
10 *
11 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
13 *
14 * IDENTIFICATION
15 * src/backend/utils/adt/ddlutils.c
16 *
17 *-------------------------------------------------------------------------
18 */
19#include "postgres.h"
20
21#include "access/genam.h"
22#include "access/htup_details.h"
23#include "access/table.h"
25#include "catalog/pg_authid.h"
27#include "catalog/pg_database.h"
30#include "commands/tablespace.h"
31#include "common/relpath.h"
32#include "funcapi.h"
33#include "mb/pg_wchar.h"
34#include "miscadmin.h"
35#include "utils/acl.h"
36#include "utils/builtins.h"
37#include "utils/datetime.h"
38#include "utils/fmgroids.h"
39#include "utils/guc.h"
40#include "utils/lsyscache.h"
41#include "utils/pg_locale.h"
42#include "utils/rel.h"
43#include "utils/ruleutils.h"
44#include "utils/syscache.h"
45#include "utils/timestamp.h"
46#include "utils/varlena.h"
47
48static void append_ddl_option(StringInfo buf, bool pretty, int indent,
49 const char *fmt, ...)
52 const char *value);
54 bool memberships);
58 bool no_owner, bool no_tablespace);
59
60
61/*
62 * Helper to append a formatted string with optional pretty-printing.
63 */
64static void
66 const char *fmt, ...)
67{
68 if (pretty)
69 {
72 }
73 else
75
76 for (;;)
77 {
78 va_list args;
79 int needed;
80
81 va_start(args, fmt);
83 va_end(args);
84 if (needed == 0)
85 break;
87 }
88}
89
90/*
91 * append_guc_value
92 * Append a GUC setting value to buf, handling GUC_LIST_QUOTE properly.
93 *
94 * Variables marked GUC_LIST_QUOTE were already fully quoted before they
95 * were stored in the setconfig array. We break the list value apart
96 * and re-quote the elements as string literals. For all other variables
97 * we simply quote the value as a single string literal.
98 *
99 * The caller has already appended "SET <name> TO " to buf.
100 */
101static void
102append_guc_value(StringInfo buf, const char *name, const char *value)
103{
104 char *rawval;
105
107
109 {
110 List *namelist;
111 bool first = true;
112
113 /* Parse string into list of identifiers */
114 if (!SplitGUCList(rawval, ',', &namelist))
115 {
116 /* this shouldn't fail really */
117 elog(ERROR, "invalid list syntax in setconfig item");
118 }
119 /* Special case: represent an empty list as NULL */
120 if (namelist == NIL)
123 {
124 if (first)
125 first = false;
126 else
129 }
131 }
132 else
134
135 pfree(rawval);
136}
137
138/*
139 * pg_get_role_ddl_internal
140 * Generate DDL statements to recreate a role
141 *
142 * Returns a List of palloc'd strings, each being a complete SQL statement.
143 * The first list element is always the CREATE ROLE statement; subsequent
144 * elements are ALTER ROLE SET statements for any role-specific or
145 * role-in-database configuration settings. If memberships is true,
146 * GRANT statements for role memberships are appended.
147 */
148static List *
150{
151 HeapTuple tuple;
154 char *rolname;
156 bool isnull;
157 Relation rel;
159 SysScanDesc scan;
161
162 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
163 if (!HeapTupleIsValid(tuple))
166 errmsg("role with OID %u does not exist", roleid)));
167
169 rolname = pstrdup(NameStr(roleform->rolname));
170
171 /* User must have SELECT privilege on pg_authid. */
173 {
174 ReleaseSysCache(tuple);
177 errmsg("permission denied for role %s", rolname)));
178 }
179
180 /*
181 * We don't support generating DDL for system roles. The primary reason
182 * for this is that users shouldn't be recreating them.
183 */
187 errmsg("role name \"%s\" is reserved", rolname),
188 errdetail("Role names starting with \"pg_\" are reserved for system roles.")));
189
191 appendStringInfo(&buf, "CREATE ROLE %s", quote_identifier(rolname));
192
193 /*
194 * Append role attributes. The order here follows the same sequence as
195 * you'd typically write them in a CREATE ROLE command, though any order
196 * is actually acceptable to the parser.
197 */
198 append_ddl_option(&buf, pretty, 4, "%s",
199 roleform->rolsuper ? "SUPERUSER" : "NOSUPERUSER");
200
201 append_ddl_option(&buf, pretty, 4, "%s",
202 roleform->rolinherit ? "INHERIT" : "NOINHERIT");
203
204 append_ddl_option(&buf, pretty, 4, "%s",
205 roleform->rolcreaterole ? "CREATEROLE" : "NOCREATEROLE");
206
207 append_ddl_option(&buf, pretty, 4, "%s",
208 roleform->rolcreatedb ? "CREATEDB" : "NOCREATEDB");
209
210 append_ddl_option(&buf, pretty, 4, "%s",
211 roleform->rolcanlogin ? "LOGIN" : "NOLOGIN");
212
213 append_ddl_option(&buf, pretty, 4, "%s",
214 roleform->rolreplication ? "REPLICATION" : "NOREPLICATION");
215
216 append_ddl_option(&buf, pretty, 4, "%s",
217 roleform->rolbypassrls ? "BYPASSRLS" : "NOBYPASSRLS");
218
219 /*
220 * CONNECTION LIMIT is only interesting if it's not -1 (the default,
221 * meaning no limit).
222 */
223 if (roleform->rolconnlimit >= 0)
224 append_ddl_option(&buf, pretty, 4, "CONNECTION LIMIT %d",
225 roleform->rolconnlimit);
226
229 &isnull);
230 if (!isnull)
231 {
232 TimestampTz ts;
233 int tz;
234 struct pg_tm tm;
235 fsec_t fsec;
236 const char *tzn;
237 char ts_str[MAXDATELEN + 1];
238
240 if (TIMESTAMP_NOT_FINITE(ts))
242 else if (timestamp2tm(ts, &tz, &tm, &fsec, &tzn, NULL) == 0)
243 EncodeDateTime(&tm, fsec, true, tz, tzn, USE_ISO_DATES, ts_str);
244 else
247 errmsg("timestamp out of range")));
248
249 append_ddl_option(&buf, pretty, 4, "VALID UNTIL %s",
251 }
252
253 ReleaseSysCache(tuple);
254
255 /*
256 * We intentionally omit PASSWORD. There's no way to retrieve the
257 * original password text from the stored hash, and even if we could,
258 * exposing passwords through a SQL function would be a security issue.
259 * Users must set passwords separately after recreating roles.
260 */
261
263
265
266 /*
267 * Now scan pg_db_role_setting for ALTER ROLE SET configurations.
268 *
269 * These can be role-wide (setdatabase = 0) or specific to a particular
270 * database (setdatabase = a valid DB OID). It generates one ALTER
271 * statement per setting.
272 */
277 ObjectIdGetDatum(roleid));
279 NULL, 1, &scankey);
280
281 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
282 {
284 Oid datid = setting->setdatabase;
285 Datum datum;
287 Datum *settings;
288 bool *nulls;
289 int nsettings;
290 char *datname = NULL;
291
292 /*
293 * If setdatabase is valid, this is a role-in-database setting;
294 * otherwise it's a role-wide setting. Look up the database name once
295 * for all settings in this row.
296 */
297 if (OidIsValid(datid))
298 {
300 /* Database has been dropped; skip all settings in this row. */
301 if (datname == NULL)
302 continue;
303 }
304
305 /*
306 * The setconfig column is a text array in "name=value" format. It
307 * should never be null for a valid row, but be defensive.
308 */
310 RelationGetDescr(rel), &isnull);
311 if (isnull)
312 continue;
313
315
317
318 for (int i = 0; i < nsettings; i++)
319 {
320 char *s,
321 *p;
322
323 if (nulls[i])
324 continue;
325
326 s = TextDatumGetCString(settings[i]);
327 p = strchr(s, '=');
328 if (p == NULL)
329 {
330 pfree(s);
331 continue;
332 }
333 *p++ = '\0';
334
335 /* Build a fresh ALTER ROLE statement for this setting */
337 appendStringInfo(&buf, "ALTER ROLE %s", quote_identifier(rolname));
338
339 if (datname != NULL)
340 appendStringInfo(&buf, " IN DATABASE %s",
342
343 appendStringInfo(&buf, " SET %s TO ",
345
346 append_guc_value(&buf, s, p);
347
349
351
352 pfree(s);
353 }
354
355 pfree(settings);
356 pfree(nulls);
358
359 if (datname != NULL)
360 pfree(datname);
361 }
362
363 systable_endscan(scan);
365
366 /*
367 * Scan pg_auth_members for role memberships. We look for rows where
368 * member = roleid, meaning this role has been granted membership in other
369 * roles.
370 */
371 if (memberships)
372 {
377 ObjectIdGetDatum(roleid));
379 NULL, 1, &scankey);
380
381 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
382 {
384 char *granted_role;
385 char *grantor;
386
387 granted_role = GetUserNameFromId(memform->roleid, false);
388 grantor = GetUserNameFromId(memform->grantor, false);
389
391 appendStringInfo(&buf, "GRANT %s TO %s",
394 appendStringInfo(&buf, " WITH ADMIN %s, INHERIT %s, SET %s",
395 memform->admin_option ? "TRUE" : "FALSE",
396 memform->inherit_option ? "TRUE" : "FALSE",
397 memform->set_option ? "TRUE" : "FALSE");
398 appendStringInfo(&buf, " GRANTED BY %s;",
399 quote_identifier(grantor));
400
402
404 pfree(grantor);
405 }
406
407 systable_endscan(scan);
409 }
410
411 pfree(buf.data);
412 pfree(rolname);
413
414 return statements;
415}
416
417/*
418 * pg_get_role_ddl
419 * Return DDL to recreate a role as a set of text rows.
420 *
421 * Each row is a complete SQL statement. The first row is always the
422 * CREATE ROLE statement; subsequent rows are ALTER ROLE SET statements
423 * and optionally GRANT statements for role memberships.
424 */
425Datum
427{
430
431 if (SRF_IS_FIRSTCALL())
432 {
433 MemoryContext oldcontext;
434 Oid roleid;
435 bool pretty;
436 bool memberships;
437
439 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
440
441 roleid = PG_GETARG_OID(0);
444
446 funcctx->user_fctx = statements;
447 funcctx->max_calls = list_length(statements);
448
449 MemoryContextSwitchTo(oldcontext);
450 }
451
453 statements = (List *) funcctx->user_fctx;
454
455 if (funcctx->call_cntr < funcctx->max_calls)
456 {
457 char *stmt;
458
459 stmt = list_nth(statements, funcctx->call_cntr);
460
462 }
463 else
464 {
467 }
468}
469
470/*
471 * pg_get_tablespace_ddl_internal
472 * Generate DDL statements to recreate a tablespace.
473 *
474 * Returns a List of palloc'd strings. The first element is the
475 * CREATE TABLESPACE statement; if the tablespace has reloptions,
476 * a second element with ALTER TABLESPACE SET (...) is appended.
477 */
478static List *
480{
481 HeapTuple tuple;
484 char *spcname;
485 char *spcowner;
486 char *path;
487 bool isNull;
488 Datum datum;
490
492 if (!HeapTupleIsValid(tuple))
495 errmsg("tablespace with OID %u does not exist",
496 tsid)));
497
499 spcname = pstrdup(NameStr(tspForm->spcname));
500
501 /* User must have SELECT privilege on pg_tablespace. */
503 {
504 ReleaseSysCache(tuple);
506 }
507
508 /*
509 * We don't support generating DDL for system tablespaces. The primary
510 * reason for this is that users shouldn't be recreating them.
511 */
515 errmsg("tablespace name \"%s\" is reserved", spcname),
516 errdetail("Tablespace names starting with \"pg_\" are reserved for system tablespaces.")));
517
519
520 /* Start building the CREATE TABLESPACE statement */
521 appendStringInfo(&buf, "CREATE TABLESPACE %s", quote_identifier(spcname));
522
523 /* Add OWNER clause */
524 if (!no_owner)
525 {
526 spcowner = GetUserNameFromId(tspForm->spcowner, false);
527 append_ddl_option(&buf, pretty, 4, "OWNER %s",
530 }
531
532 /* Find tablespace directory path */
533 path = get_tablespace_location(tsid);
534
535 /* Add directory LOCATION (path), if it exists */
536 if (path[0] != '\0')
537 {
538 /*
539 * Special case: if the tablespace was created with GUC
540 * "allow_in_place_tablespaces = true" and "LOCATION ''", path will
541 * begin with "pg_tblspc/". In that case, show "LOCATION ''" as the
542 * user originally specified.
543 */
545 append_ddl_option(&buf, pretty, 4, "LOCATION ''");
546 else
547 append_ddl_option(&buf, pretty, 4, "LOCATION %s",
548 quote_literal_cstr(path));
549 }
550 pfree(path);
551
554
555 /* Check for tablespace options */
556 datum = SysCacheGetAttr(TABLESPACEOID, tuple,
558 if (!isNull)
559 {
561 appendStringInfo(&buf, "ALTER TABLESPACE %s SET (",
563 get_reloptions(&buf, datum);
566 }
567
568 ReleaseSysCache(tuple);
569 pfree(spcname);
570 pfree(buf.data);
571
572 return statements;
573}
574
575/*
576 * pg_get_tablespace_ddl_srf - common SRF logic for tablespace DDL
577 */
578static Datum
580{
583
584 if (SRF_IS_FIRSTCALL())
585 {
586 MemoryContext oldcontext;
587 bool pretty;
588 bool no_owner;
589
591 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
592
595
597 funcctx->user_fctx = statements;
598 funcctx->max_calls = list_length(statements);
599
600 MemoryContextSwitchTo(oldcontext);
601 }
602
604 statements = (List *) funcctx->user_fctx;
605
606 if (funcctx->call_cntr < funcctx->max_calls)
607 {
608 char *stmt;
609
610 stmt = (char *) list_nth(statements, funcctx->call_cntr);
611
613 }
614 else
615 {
618 }
619}
620
621/*
622 * pg_get_tablespace_ddl_oid
623 * Return DDL to recreate a tablespace, taking OID.
624 */
625Datum
627{
628 Oid tsid = PG_GETARG_OID(0);
629
630 return pg_get_tablespace_ddl_srf(fcinfo, tsid);
631}
632
633/*
634 * pg_get_tablespace_ddl_name
635 * Return DDL to recreate a tablespace, taking name.
636 */
637Datum
645
646/*
647 * pg_get_database_ddl_internal
648 * Generate DDL statements to recreate a database.
649 *
650 * Returns a List of palloc'd strings. The first element is the
651 * CREATE DATABASE statement; subsequent elements are ALTER DATABASE
652 * statements for properties and configuration settings.
653 */
654static List *
656 bool no_owner, bool no_tablespace)
657{
658 HeapTuple tuple;
661 bool isnull;
662 Datum datum;
663 const char *encoding;
664 char *dbname;
665 char *collate;
666 char *ctype;
667 Relation rel;
669 SysScanDesc scan;
672
674 if (!HeapTupleIsValid(tuple))
677 errmsg("database with OID %u does not exist", dbid)));
678
679 /* User must have connect privilege for target database. */
681 if (aclresult != ACLCHECK_OK)
683 get_database_name(dbid));
684
686 dbname = pstrdup(NameStr(dbform->datname));
687
688 /*
689 * Reject invalid databases. Deparsing a pg_database row in invalid state
690 * can produce SQL that is not executable, such as CONNECTION LIMIT = -2.
691 */
695 errmsg("cannot generate DDL for invalid database \"%s\"",
696 dbname)));
697
698 /*
699 * We don't support generating DDL for system databases. The primary
700 * reason for this is that users shouldn't be recreating them.
701 */
702 if (strcmp(dbname, "template0") == 0 || strcmp(dbname, "template1") == 0)
705 errmsg("database \"%s\" is a system database", dbname),
706 errdetail("DDL generation is not supported for template0 and template1.")));
707
709
710 /* --- Build CREATE DATABASE statement --- */
711 appendStringInfo(&buf, "CREATE DATABASE %s", quote_identifier(dbname));
712
713 /*
714 * Always use template0: the target database already contains the catalog
715 * data from whatever template was used originally, so we must start from
716 * the pristine template to avoid duplication.
717 */
718 append_ddl_option(&buf, pretty, 4, "WITH TEMPLATE = template0");
719
720 /* ENCODING */
722 if (strlen(encoding) > 0)
723 append_ddl_option(&buf, pretty, 4, "ENCODING = %s",
725
726 /* LOCALE_PROVIDER */
727 if (dbform->datlocprovider == COLLPROVIDER_BUILTIN ||
728 dbform->datlocprovider == COLLPROVIDER_ICU ||
729 dbform->datlocprovider == COLLPROVIDER_LIBC)
730 append_ddl_option(&buf, pretty, 4, "LOCALE_PROVIDER = %s",
731 collprovider_name(dbform->datlocprovider));
732 else
735 errmsg("unrecognized locale provider: %c",
736 dbform->datlocprovider)));
737
738 /* LOCALE, LC_COLLATE, LC_CTYPE */
739 datum = SysCacheGetAttr(DATABASEOID, tuple,
741 collate = isnull ? NULL : TextDatumGetCString(datum);
742 datum = SysCacheGetAttr(DATABASEOID, tuple,
744 ctype = isnull ? NULL : TextDatumGetCString(datum);
745 if (collate != NULL && ctype != NULL && strcmp(collate, ctype) == 0)
746 {
747 append_ddl_option(&buf, pretty, 4, "LOCALE = %s",
748 quote_literal_cstr(collate));
749 }
750 else
751 {
752 if (collate != NULL)
753 append_ddl_option(&buf, pretty, 4, "LC_COLLATE = %s",
754 quote_literal_cstr(collate));
755 if (ctype != NULL)
756 append_ddl_option(&buf, pretty, 4, "LC_CTYPE = %s",
757 quote_literal_cstr(ctype));
758 }
759
760 /* LOCALE (provider-specific) */
761 datum = SysCacheGetAttr(DATABASEOID, tuple,
763 if (!isnull)
764 {
765 const char *locale = TextDatumGetCString(datum);
766
767 if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
768 append_ddl_option(&buf, pretty, 4, "BUILTIN_LOCALE = %s",
769 quote_literal_cstr(locale));
770 else if (dbform->datlocprovider == COLLPROVIDER_ICU)
771 append_ddl_option(&buf, pretty, 4, "ICU_LOCALE = %s",
772 quote_literal_cstr(locale));
773 }
774
775 /* ICU_RULES */
776 datum = SysCacheGetAttr(DATABASEOID, tuple,
778 if (!isnull && dbform->datlocprovider == COLLPROVIDER_ICU)
779 append_ddl_option(&buf, pretty, 4, "ICU_RULES = %s",
781
782 /* TABLESPACE */
783 if (!no_tablespace && OidIsValid(dbform->dattablespace))
784 {
785 char *spcname = get_tablespace_name(dbform->dattablespace);
786
787 if (spcname == NULL)
790 errmsg("tablespace with OID %u does not exist",
791 dbform->dattablespace),
792 errdetail("It may have been concurrently dropped.")));
793
794 if (pg_strcasecmp(spcname, "pg_default") != 0)
795 append_ddl_option(&buf, pretty, 4, "TABLESPACE = %s",
797 }
798
801
802 /* OWNER */
803 if (!no_owner && OidIsValid(dbform->datdba))
804 {
805 char *owner = GetUserNameFromId(dbform->datdba, false);
806
808 appendStringInfo(&buf, "ALTER DATABASE %s OWNER TO %s;",
810 pfree(owner);
812 }
813
814 /* CONNECTION LIMIT */
815 if (dbform->datconnlimit != -1)
816 {
818 appendStringInfo(&buf, "ALTER DATABASE %s CONNECTION LIMIT = %d;",
819 quote_identifier(dbname), dbform->datconnlimit);
821 }
822
823 /* IS_TEMPLATE */
824 if (dbform->datistemplate)
825 {
827 appendStringInfo(&buf, "ALTER DATABASE %s IS_TEMPLATE = true;",
830 }
831
832 /* ALLOW_CONNECTIONS */
833 if (!dbform->datallowconn)
834 {
836 appendStringInfo(&buf, "ALTER DATABASE %s ALLOW_CONNECTIONS = false;",
839 }
840
841 ReleaseSysCache(tuple);
842
843 /*
844 * Now scan pg_db_role_setting for ALTER DATABASE SET configurations.
845 *
846 * It is only database-wide (setrole = 0). It generates one ALTER
847 * statement per setting.
848 */
853 ObjectIdGetDatum(dbid));
858
860 NULL, 2, scankey);
861
862 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
863 {
865 Datum *settings;
866 bool *nulls;
867 int nsettings;
868
869 /*
870 * The setconfig column is a text array in "name=value" format. It
871 * should never be null for a valid row, but be defensive.
872 */
874 RelationGetDescr(rel), &isnull);
875 if (isnull)
876 continue;
877
879
881
882 for (int i = 0; i < nsettings; i++)
883 {
884 char *s,
885 *p;
886
887 if (nulls[i])
888 continue;
889
890 s = TextDatumGetCString(settings[i]);
891 p = strchr(s, '=');
892 if (p == NULL)
893 {
894 pfree(s);
895 continue;
896 }
897 *p++ = '\0';
898
900 appendStringInfo(&buf, "ALTER DATABASE %s SET %s TO ",
903
904 append_guc_value(&buf, s, p);
905
907
909
910 pfree(s);
911 }
912
913 pfree(settings);
914 pfree(nulls);
916 }
917
918 systable_endscan(scan);
920
921 pfree(buf.data);
922 pfree(dbname);
923
924 return statements;
925}
926
927/*
928 * pg_get_database_ddl
929 * Return DDL to recreate a database as a set of text rows.
930 */
931Datum
933{
936
937 if (SRF_IS_FIRSTCALL())
938 {
939 MemoryContext oldcontext;
940 Oid dbid;
941 bool pretty;
942 bool no_owner;
943 bool no_tablespace;
944
946 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
947
948 dbid = PG_GETARG_OID(0);
952
955 funcctx->user_fctx = statements;
956 funcctx->max_calls = list_length(statements);
957
958 MemoryContextSwitchTo(oldcontext);
959 }
960
962 statements = (List *) funcctx->user_fctx;
963
964 if (funcctx->call_cntr < funcctx->max_calls)
965 {
966 char *stmt;
967
968 stmt = list_nth(statements, funcctx->call_cntr);
969
971 }
972 else
973 {
976 }
977}
AclResult
Definition acl.h:183
@ ACLCHECK_NO_PRIV
Definition acl.h:185
@ ACLCHECK_OK
Definition acl.h:184
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3902
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition aclchk.c:4105
#define DatumGetArrayTypePCopy(X)
Definition array.h:262
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
char * get_tablespace_name(Oid spc_oid)
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition datetime.c:4496
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition timestamp.c:1591
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition timestamp.c:1918
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:894
#define pg_attribute_printf(f, a)
Definition c.h:327
#define OidIsValid(objectId)
Definition c.h:917
bool IsReservedName(const char *name)
Definition catalog.c:305
int64 TimestampTz
Definition timestamp.h:39
int32 fsec_t
Definition timestamp.h:41
#define TIMESTAMP_NOT_FINITE(j)
Definition timestamp.h:169
bool database_is_invalid_form(Form_pg_database datform)
Datum pg_get_database_ddl(PG_FUNCTION_ARGS)
Definition ddlutils.c:932
static List * pg_get_tablespace_ddl_internal(Oid tsid, bool pretty, bool no_owner)
Definition ddlutils.c:479
Datum pg_get_tablespace_ddl_oid(PG_FUNCTION_ARGS)
Definition ddlutils.c:626
static List * pg_get_role_ddl_internal(Oid roleid, bool pretty, bool memberships)
Definition ddlutils.c:149
static List * pg_get_database_ddl_internal(Oid dbid, bool pretty, bool no_owner, bool no_tablespace)
Definition ddlutils.c:655
Datum pg_get_tablespace_ddl_name(PG_FUNCTION_ARGS)
Definition ddlutils.c:638
static void append_ddl_option(StringInfo buf, bool pretty, int indent, const char *fmt,...) pg_attribute_printf(4
Definition ddlutils.c:65
static Datum pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid)
Definition ddlutils.c:579
static void static void append_guc_value(StringInfo buf, const char *name, const char *value)
Definition ddlutils.c:102
Datum pg_get_role_ddl(PG_FUNCTION_ARGS)
Definition ddlutils.c:426
int errcode(int sqlerrcode)
Definition elog.c:875
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_NAME(n)
Definition fmgr.h:279
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
int GetConfigOptionFlags(const char *name, bool missing_ok)
Definition guc.c:4354
#define GUC_LIST_QUOTE
Definition guc.h:215
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define MAXDATELEN
Definition datetime.h:200
#define stmt
static struct @175 value
static char * encoding
Definition initdb.c:139
int i
Definition isn.c:77
List * lappend(List *list, void *datum)
Definition list.c:339
void list_free(List *list)
Definition list.c:1546
void list_free_deep(List *list)
Definition list.c:1560
static struct pg_tm tm
Definition localtime.c:148
#define AccessShareLock
Definition lockdefs.h:36
char * get_database_name(Oid dbid)
Definition lsyscache.c:1392
char * pstrdup(const char *in)
Definition mcxt.c:1910
void pfree(void *pointer)
Definition mcxt.c:1619
#define USE_ISO_DATES
Definition miscadmin.h:240
Oid GetUserId(void)
Definition miscinit.c:470
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c:990
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
@ OBJECT_TABLESPACE
@ OBJECT_DATABASE
#define ACL_CONNECT
Definition parsenodes.h:87
#define ACL_SELECT
Definition parsenodes.h:77
END_CATALOG_STRUCT typedef FormData_pg_auth_members * Form_pg_auth_members
NameData rolname
Definition pg_authid.h:36
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
NameData datname
Definition pg_database.h:37
END_CATALOG_STRUCT typedef FormData_pg_database * Form_pg_database
END_CATALOG_STRUCT typedef FormData_pg_db_role_setting * Form_pg_db_role_setting
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
static void * list_nth(const List *list, int n)
Definition pg_list.h:331
char * get_tablespace_location(Oid tablespaceOid)
END_CATALOG_STRUCT typedef FormData_pg_tablespace * Form_pg_tablespace
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pg_encoding_to_char
Definition pg_wchar.h:483
int pg_strcasecmp(const char *s1, const char *s2)
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
#define InvalidOid
unsigned int Oid
static int fb(int x)
char * quote_literal_cstr(const char *rawstr)
Definition quote.c:101
#define RelationGetDescr(relation)
Definition rel.h:542
#define PG_TBLSPC_DIR_SLASH
Definition relpath.h:42
const char * quote_identifier(const char *ident)
void get_reloptions(StringInfo buf, Datum reloptions)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
char * dbname
Definition streamutil.c:49
int appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
Definition stringinfo.c:187
void resetStringInfo(StringInfo str)
Definition stringinfo.c:126
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void enlargeStringInfo(StringInfo str, int needed)
Definition stringinfo.c:337
void appendStringInfoSpaces(StringInfo str, int count)
Definition stringinfo.c:260
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
Definition pg_list.h:54
Definition c.h:889
Definition pgtime.h:35
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
static TimestampTz DatumGetTimestampTz(Datum X)
Definition timestamp.h:34
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition varlena.c:3063
const char * name