mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Adds domain dumping support to pg_dump.
Rod Taylor
This commit is contained in:
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.245 2002/04/05 00:31:31 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.246 2002/04/05 11:51:12 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -77,6 +77,7 @@ typedef enum _formatLiteralOptions
|
|||||||
static void dumpComment(Archive *fout, const char *target, const char *oid,
|
static void dumpComment(Archive *fout, const char *target, const char *oid,
|
||||||
const char *classname, int subid,
|
const char *classname, int subid,
|
||||||
const char *((*deps)[]));
|
const char *((*deps)[]));
|
||||||
|
static void dumpOneDomain(Archive *fout, TypeInfo *tinfo);
|
||||||
static void dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly);
|
static void dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly);
|
||||||
static void dumpACL(Archive *fout, TableInfo tbinfo);
|
static void dumpACL(Archive *fout, TableInfo tbinfo);
|
||||||
static void dumpTriggers(Archive *fout, const char *tablename,
|
static void dumpTriggers(Archive *fout, const char *tablename,
|
||||||
@ -91,6 +92,7 @@ static Oid findLastBuiltinOid_V71(const char *);
|
|||||||
static Oid findLastBuiltinOid_V70(void);
|
static Oid findLastBuiltinOid_V70(void);
|
||||||
static void setMaxOid(Archive *fout);
|
static void setMaxOid(Archive *fout);
|
||||||
|
|
||||||
|
|
||||||
static void AddAcl(char *aclbuf, const char *keyword);
|
static void AddAcl(char *aclbuf, const char *keyword);
|
||||||
static char *GetPrivileges(Archive *AH, const char *s);
|
static char *GetPrivileges(Archive *AH, const char *s);
|
||||||
|
|
||||||
@ -1352,6 +1354,7 @@ getTypes(int *numTypes)
|
|||||||
int i_typisdefined;
|
int i_typisdefined;
|
||||||
int i_usename;
|
int i_usename;
|
||||||
int i_typedefn;
|
int i_typedefn;
|
||||||
|
int i_typtype;
|
||||||
|
|
||||||
/* find all base types */
|
/* find all base types */
|
||||||
|
|
||||||
@ -1368,7 +1371,7 @@ getTypes(int *numTypes)
|
|||||||
"typinput, typoutput, typreceive, typsend, typelem, typdelim, "
|
"typinput, typoutput, typreceive, typsend, typelem, typdelim, "
|
||||||
"typdefault, typrelid, typalign, 'p'::char as typstorage, typbyval, typisdefined, "
|
"typdefault, typrelid, typalign, 'p'::char as typstorage, typbyval, typisdefined, "
|
||||||
"(select usename from pg_user where typowner = usesysid) as usename, "
|
"(select usename from pg_user where typowner = usesysid) as usename, "
|
||||||
"typname as typedefn "
|
"typname as typedefn, typtype "
|
||||||
"from pg_type");
|
"from pg_type");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1377,7 +1380,7 @@ getTypes(int *numTypes)
|
|||||||
"typinput, typoutput, typreceive, typsend, typelem, typdelim, "
|
"typinput, typoutput, typreceive, typsend, typelem, typdelim, "
|
||||||
"typdefault, typrelid, typalign, typstorage, typbyval, typisdefined, "
|
"typdefault, typrelid, typalign, typstorage, typbyval, typisdefined, "
|
||||||
"(select usename from pg_user where typowner = usesysid) as usename, "
|
"(select usename from pg_user where typowner = usesysid) as usename, "
|
||||||
"format_type(pg_type.oid, NULL) as typedefn "
|
"format_type(pg_type.oid, NULL) as typedefn, typtype "
|
||||||
"from pg_type");
|
"from pg_type");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1412,6 +1415,7 @@ getTypes(int *numTypes)
|
|||||||
i_typisdefined = PQfnumber(res, "typisdefined");
|
i_typisdefined = PQfnumber(res, "typisdefined");
|
||||||
i_usename = PQfnumber(res, "usename");
|
i_usename = PQfnumber(res, "usename");
|
||||||
i_typedefn = PQfnumber(res, "typedefn");
|
i_typedefn = PQfnumber(res, "typedefn");
|
||||||
|
i_typtype = PQfnumber(res, "typtype");
|
||||||
|
|
||||||
for (i = 0; i < ntups; i++)
|
for (i = 0; i < ntups; i++)
|
||||||
{
|
{
|
||||||
@ -1435,6 +1439,7 @@ getTypes(int *numTypes)
|
|||||||
tinfo[i].typstorage = strdup(PQgetvalue(res, i, i_typstorage));
|
tinfo[i].typstorage = strdup(PQgetvalue(res, i, i_typstorage));
|
||||||
tinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
tinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
|
||||||
tinfo[i].typedefn = strdup(PQgetvalue(res, i, i_typedefn));
|
tinfo[i].typedefn = strdup(PQgetvalue(res, i, i_typedefn));
|
||||||
|
tinfo[i].typtype = strdup(PQgetvalue(res, i, i_typtype));
|
||||||
|
|
||||||
if (strlen(tinfo[i].usename) == 0)
|
if (strlen(tinfo[i].usename) == 0)
|
||||||
write_msg(NULL, "WARNING: owner of data type %s appears to be invalid\n",
|
write_msg(NULL, "WARNING: owner of data type %s appears to be invalid\n",
|
||||||
@ -3188,6 +3193,88 @@ dumpDBComment(Archive *fout)
|
|||||||
destroyPQExpBuffer(query);
|
destroyPQExpBuffer(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dumpOneDomain
|
||||||
|
* wites out to fout the queries to recrease a user-defined domains
|
||||||
|
* as requested by dumpTypes
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dumpOneDomain(Archive *fout, TypeInfo *tinfo)
|
||||||
|
{
|
||||||
|
PQExpBuffer q = createPQExpBuffer();
|
||||||
|
PQExpBuffer delq = createPQExpBuffer();
|
||||||
|
|
||||||
|
PGresult *res;
|
||||||
|
PQExpBuffer query = createPQExpBuffer();
|
||||||
|
int ntups;
|
||||||
|
const char *((*deps)[]);
|
||||||
|
int depIdx = 0;
|
||||||
|
|
||||||
|
|
||||||
|
deps = malloc(sizeof(char *) * 10);
|
||||||
|
|
||||||
|
/* Fetch domain specific details */
|
||||||
|
resetPQExpBuffer(query);
|
||||||
|
appendPQExpBuffer(query, "SELECT typnotnull, "
|
||||||
|
"format_type(typbasetype, typtypmod) as typdefn, "
|
||||||
|
"typbasetype "
|
||||||
|
"FROM pg_type "
|
||||||
|
"WHERE typname = '%s'",
|
||||||
|
tinfo->typname);
|
||||||
|
|
||||||
|
res = PQexec(g_conn, query->data);
|
||||||
|
if (!res ||
|
||||||
|
PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
|
{
|
||||||
|
write_msg(NULL, "query to obtain domain information failed: %s", PQerrorMessage(g_conn));
|
||||||
|
exit_nicely();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expecting a single result only */
|
||||||
|
ntups = PQntuples(res);
|
||||||
|
if (ntups != 1)
|
||||||
|
write_msg(NULL, "Domain %s non-existant.", fmtId(tinfo->typname, force_quotes));
|
||||||
|
|
||||||
|
|
||||||
|
/* Drop the old copy */
|
||||||
|
resetPQExpBuffer(delq);
|
||||||
|
appendPQExpBuffer(delq, "DROP DOMAIN %s RESTRICT;\n", fmtId(tinfo->typname, force_quotes));
|
||||||
|
|
||||||
|
resetPQExpBuffer(q);
|
||||||
|
appendPQExpBuffer(q,
|
||||||
|
"CREATE DOMAIN %s AS %s",
|
||||||
|
fmtId(tinfo->typname, force_quotes),
|
||||||
|
PQgetvalue(res, 0, PQfnumber(res, "typdefn"))
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Depends on the base type */
|
||||||
|
(*deps)[depIdx++] = strdup(PQgetvalue(res, 0, PQfnumber(res, "typbasetype")));
|
||||||
|
|
||||||
|
if (PQgetvalue(res, 0, PQfnumber(res, "typnotnull"))[0] == 't')
|
||||||
|
appendPQExpBuffer(q, " NOT NULL");
|
||||||
|
|
||||||
|
if (tinfo->typdefault)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(q,
|
||||||
|
" DEFAULT %s",
|
||||||
|
tinfo->typdefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendPQExpBuffer(q, ";\n");
|
||||||
|
|
||||||
|
|
||||||
|
(*deps)[depIdx++] = NULL; /* End of List */
|
||||||
|
|
||||||
|
ArchiveEntry(fout, tinfo->oid, tinfo->typname, "DOMAIN", deps,
|
||||||
|
q->data, delq->data, "", tinfo->usename, NULL, NULL);
|
||||||
|
|
||||||
|
/*** Dump Domain Comments ***/
|
||||||
|
resetPQExpBuffer(q);
|
||||||
|
|
||||||
|
appendPQExpBuffer(q, "DOMAIN %s", fmtId(tinfo->typname, force_quotes));
|
||||||
|
dumpComment(fout, q->data, tinfo->oid, "pg_type", 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpTypes
|
* dumpTypes
|
||||||
* writes out to fout the queries to recreate all the user-defined types
|
* writes out to fout the queries to recreate all the user-defined types
|
||||||
@ -3223,6 +3310,13 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
|
|||||||
(strcmp(tinfo[i].typinput, "array_in") == 0))
|
(strcmp(tinfo[i].typinput, "array_in") == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Dump out domains as we run across them */
|
||||||
|
if (strcmp(tinfo[i].typtype, "d") == 0) {
|
||||||
|
dumpOneDomain(fout, &tinfo[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
deps = malloc(sizeof(char *) * 10);
|
deps = malloc(sizeof(char *) * 10);
|
||||||
depIdx = 0;
|
depIdx = 0;
|
||||||
|
|
||||||
@ -3318,6 +3412,8 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
|
|||||||
ArchiveEntry(fout, tinfo[i].oid, tinfo[i].typname, "TYPE", deps,
|
ArchiveEntry(fout, tinfo[i].oid, tinfo[i].typname, "TYPE", deps,
|
||||||
q->data, delq->data, "", tinfo[i].usename, NULL, NULL);
|
q->data, delq->data, "", tinfo[i].usename, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*** Dump Type Comments ***/
|
/*** Dump Type Comments ***/
|
||||||
|
|
||||||
resetPQExpBuffer(q);
|
resetPQExpBuffer(q);
|
||||||
@ -4294,6 +4390,36 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
|||||||
tblinfo[i].check_expr[k]);
|
tblinfo[i].check_expr[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Primary Key */
|
||||||
|
if (tblinfo[i].pkIndexOid != NULL)
|
||||||
|
{
|
||||||
|
PQExpBuffer consDef;
|
||||||
|
|
||||||
|
/* Find the corresponding index */
|
||||||
|
for (k = 0; k < numIndexes; k++)
|
||||||
|
{
|
||||||
|
if (strcmp(indinfo[k].indexreloid,
|
||||||
|
tblinfo[i].pkIndexOid) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k >= numIndexes)
|
||||||
|
{
|
||||||
|
write_msg(NULL, "dumpTables(): failed sanity check, could not find index (%s) for primary key constraint\n",
|
||||||
|
tblinfo[i].pkIndexOid);
|
||||||
|
exit_nicely();
|
||||||
|
}
|
||||||
|
|
||||||
|
consDef = getPKconstraint(&tblinfo[i], &indinfo[k]);
|
||||||
|
|
||||||
|
if ((actual_atts + tblinfo[i].ncheck) > 0)
|
||||||
|
appendPQExpBuffer(q, ",\n\t");
|
||||||
|
|
||||||
|
appendPQExpBuffer(q, "%s", consDef->data);
|
||||||
|
|
||||||
|
destroyPQExpBuffer(consDef);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Primary Key: In versions of PostgreSQL prior to 7.2, we
|
* Primary Key: In versions of PostgreSQL prior to 7.2, we
|
||||||
* needed to include the primary key in the table definition.
|
* needed to include the primary key in the table definition.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_dump.h,v 1.79 2002/04/05 00:31:32 tgl Exp $
|
* $Id: pg_dump.h,v 1.80 2002/04/05 11:51:13 momjian Exp $
|
||||||
*
|
*
|
||||||
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
||||||
*
|
*
|
||||||
@ -53,6 +53,7 @@ typedef struct _typeInfo
|
|||||||
char *typstorage;
|
char *typstorage;
|
||||||
char *usename;
|
char *usename;
|
||||||
char *typedefn;
|
char *typedefn;
|
||||||
|
char *typtype;
|
||||||
int passedbyvalue;
|
int passedbyvalue;
|
||||||
int isArray;
|
int isArray;
|
||||||
int isDefined;
|
int isDefined;
|
||||||
|
Reference in New Issue
Block a user