1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

First pass at schema-fying pg_dump/pg_restore. Much to do still,

but the basic capability seems to work.
This commit is contained in:
Tom Lane
2002-05-10 22:36:27 +00:00
parent 1011fb651d
commit 9f0ae0c820
13 changed files with 4137 additions and 3801 deletions

View File

@ -5,25 +5,7 @@
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.31 2002/01/18 19:17:05 momjian Exp $
*
* NOTES
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
*
* - Check results of PQ routines more carefully.
*
* Modifications - 19-Mar-2001 - pjw@rhyme.com.au
*
* - Avoid forcing table name to lower case in FixupBlobXrefs!
*
*
* Modifications - 18-Jan-2002 - pjw@rhyme.com.au
*
* - Split ExecuteSqlCommandBuf into 3 routines for (slightly) improved
* clarity. Modify loop to cater for COPY commands buried in the SQL
* command buffer (prev version assumed COPY command was executed
* in prior call). This was to fix the buf in the 'set max oid' code.
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.32 2002/05/10 22:36:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -219,57 +201,6 @@ _check_database_version(ArchiveHandle *AH, bool ignoreVersion)
}
}
/*
* Check if a given user is a superuser.
*/
int
UserIsSuperuser(ArchiveHandle *AH, char *user)
{
PQExpBuffer qry = createPQExpBuffer();
PGresult *res;
int i_usesuper;
int ntups;
int isSuper;
/* Get the superuser setting */
appendPQExpBuffer(qry, "select usesuper from pg_user where usename = '%s'", user);
res = PQexec(AH->connection, qry->data);
if (!res)
die_horribly(AH, modulename, "null result checking superuser status of %s\n", user);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
die_horribly(AH, modulename, "could not check superuser status of %s: %s",
user, PQerrorMessage(AH->connection));
ntups = PQntuples(res);
if (ntups == 0)
isSuper = 0;
else
{
i_usesuper = PQfnumber(res, "usesuper");
isSuper = (strcmp(PQgetvalue(res, 0, i_usesuper), "t") == 0);
}
PQclear(res);
destroyPQExpBuffer(qry);
return isSuper;
}
int
ConnectedUserIsSuperuser(ArchiveHandle *AH)
{
return UserIsSuperuser(AH, PQuser(AH->connection));
}
char *
ConnectedUser(ArchiveHandle *AH)
{
return PQuser(AH->connection);
}
/*
* Reconnect to the server. If dbname is not NULL, use that database,
* else the one associated with the archive handle. If username is
@ -310,6 +241,11 @@ ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
AH->username = strdup(newusername);
/* XXX Why don't we update AH->dbname? */
/* don't assume we still know the output schema */
if (AH->currSchema)
free(AH->currSchema);
AH->currSchema = strdup("");
return 1;
}
@ -481,13 +417,6 @@ ConnectDatabase(Archive *AHX,
PQsetNoticeProcessor(AH->connection, notice_processor, NULL);
/*
* AH->currUser = PQuser(AH->connection);
*
* Removed because it prevented an initial \connect when dumping to SQL
* in pg_dump.
*/
return AH->connection;
}
@ -775,8 +704,9 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, void *qryv, int bufLen)
}
void
FixupBlobRefs(ArchiveHandle *AH, char *tablename)
FixupBlobRefs(ArchiveHandle *AH, TocEntry *te)
{
PQExpBuffer tblName;
PQExpBuffer tblQry;
PGresult *res,
*uRes;
@ -784,44 +714,55 @@ FixupBlobRefs(ArchiveHandle *AH, char *tablename)
n;
char *attr;
if (strcmp(tablename, BLOB_XREF_TABLE) == 0)
if (strcmp(te->name, BLOB_XREF_TABLE) == 0)
return;
tblName = createPQExpBuffer();
tblQry = createPQExpBuffer();
appendPQExpBuffer(tblQry, "SELECT a.attname FROM pg_class c, pg_attribute a, pg_type t "
" WHERE a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid "
" AND t.typname in ('oid', 'lo') AND c.relname = '%s';", tablename);
if (te->namespace && strlen(te->namespace) > 0)
appendPQExpBuffer(tblName, "%s.",
fmtId(te->namespace, false));
appendPQExpBuffer(tblName, "%s",
fmtId(te->name, false));
appendPQExpBuffer(tblQry,
"SELECT a.attname FROM "
"pg_catalog.pg_attribute a, pg_catalog.pg_type t "
"WHERE a.attnum > 0 AND a.attrelid = '%s'::regclass "
"AND a.atttypid = t.oid AND t.typname in ('oid', 'lo')",
tblName->data);
res = PQexec(AH->blobConnection, tblQry->data);
if (!res)
die_horribly(AH, modulename, "could not find oid columns of table \"%s\": %s",
tablename, PQerrorMessage(AH->connection));
te->name, PQerrorMessage(AH->connection));
if ((n = PQntuples(res)) == 0)
{
/* nothing to do */
ahlog(AH, 1, "no OID type columns in table %s\n", tablename);
ahlog(AH, 1, "no OID type columns in table %s\n", te->name);
}
for (i = 0; i < n; i++)
{
attr = PQgetvalue(res, i, 0);
ahlog(AH, 1, "fixing large object cross-references for %s.%s\n", tablename, attr);
ahlog(AH, 1, "fixing large object cross-references for %s.%s\n",
te->name, attr);
resetPQExpBuffer(tblQry);
/*
* We should use coalesce here (rather than 'exists'), but it
* seems to be broken in 7.0.2 (weird optimizer strategy)
*/
appendPQExpBuffer(tblQry, "UPDATE \"%s\" SET \"%s\" = ", tablename, attr);
appendPQExpBuffer(tblQry, " (SELECT x.newOid FROM \"%s\" x WHERE x.oldOid = \"%s\".\"%s\")",
BLOB_XREF_TABLE, tablename, attr);
appendPQExpBuffer(tblQry, " where exists"
"(select * from %s x where x.oldOid = \"%s\".\"%s\");",
BLOB_XREF_TABLE, tablename, attr);
/* Can't use fmtId twice in one call... */
appendPQExpBuffer(tblQry,
"UPDATE %s SET %s = %s.newOid",
tblName->data, fmtId(attr, false),
BLOB_XREF_TABLE);
appendPQExpBuffer(tblQry,
" FROM %s WHERE %s.oldOid = %s.%s",
BLOB_XREF_TABLE,
BLOB_XREF_TABLE,
tblName->data, fmtId(attr, false));
ahlog(AH, 10, "SQL: %s\n", tblQry->data);
@ -829,17 +770,18 @@ FixupBlobRefs(ArchiveHandle *AH, char *tablename)
if (!uRes)
die_horribly(AH, modulename,
"could not update column \"%s\" of table \"%s\": %s",
attr, tablename, PQerrorMessage(AH->blobConnection));
attr, te->name, PQerrorMessage(AH->blobConnection));
if (PQresultStatus(uRes) != PGRES_COMMAND_OK)
die_horribly(AH, modulename,
"error while updating column \"%s\" of table \"%s\": %s",
attr, tablename, PQerrorMessage(AH->blobConnection));
attr, te->name, PQerrorMessage(AH->blobConnection));
PQclear(uRes);
}
PQclear(res);
destroyPQExpBuffer(tblName);
destroyPQExpBuffer(tblQry);
}