Hi again, Tom Lane [2006-02-18 14:34 -0500]: > >>> The core problem is that we want to not restore objects (mainly > >>> tables) in the destination database which already exist. > >> > >> Why is this a problem? It's already the default behavior --- the > >> creation commands fail but pg_restore keeps going. > > > The problem is that pg_restore would restore the TABLE DATA object, > > although we don't want that (the postgis specific tables are > > pre-populated by PostGIS itself, and should not be altered by the > > upgrade. > > Hm. Rather than a variant of the -L facility (which is hard to use, > and I don't see your proposal being much easier), maybe what's wanted > is just a flag saying "don't try to restore data into any table whose > creation command fails". Maybe that should even be the default ... > and you could extend it to indexes and constraints on such tables too, > as those would likely end up being duplicated as well.
My first stab at this is a patch which only does the minimal changes, just to get me going. If the restoration of a TABLE object fails, it marks the corresponding TABLE DATA object as to be ignored. Do you think the current patch is a valid approach? Since this changes the behaviour of pg_restore, this should probably become an option, e. g. -D / --ignore-existing-table-data. I'll do this if you agree to the principle of the current patch. For convenience, I wrote a small test script which demonstrates the behaviour. The table 'userdata' should be restored, while the table 'auxdata' is already present in the destination db, and its contents should not be modified. Output with pg_restore from 8.1.3: ------------------- snip ------------------------ $ LC_ALL=C sudo -u postgres ./test-pg_restore-existing.sh === create empty databases === === populating old database === === pre-creating auxdata in new database === === restoring old to new === pg_restore: connecting to database for restore pg_restore: creating SCHEMA public pg_restore: creating COMMENT SCHEMA public pg_restore: creating TABLE auxdata pg_restore: [archiver (db)] Error while PROCESSING TOC: pg_restore: [archiver (db)] Error from TOC entry 1183; 1259 17184 TABLE auxdata postgres pg_restore: [archiver (db)] could not execute query: FEHLER: Relation »auxdata« existiert bereits Command was: CREATE TABLE auxdata ( x integer ); pg_restore: creating TABLE userdata pg_restore: restoring data for table "auxdata" pg_restore: restoring data for table "userdata" pg_restore: setting owner and privileges for SCHEMA public pg_restore: setting owner and privileges for COMMENT SCHEMA public pg_restore: setting owner and privileges for ACL public pg_restore: setting owner and privileges for TABLE auxdata pg_restore: setting owner and privileges for TABLE userdata WARNING: errors ignored on restore: 1 pg_restore failed with 1 === new/userdata: === 42 256 === new/auxdata: === -1 -2 1 2 ------------------- snip ------------------------ Output with patched pg_restore: ------------------- snip ------------------------ $ LC_ALL=C sudo -u postgres ./test-pg_restore-existing.sh === create empty databases === === populating old database === === pre-creating auxdata in new database === === restoring old to new === pg_restore: connecting to database for restore pg_restore: creating SCHEMA public pg_restore: creating COMMENT SCHEMA public pg_restore: creating TABLE auxdata pg_restore: [archiver (db)] Error while PROCESSING TOC: pg_restore: [archiver (db)] Error from TOC entry 1183; 1259 17194 TABLE auxdata postgres pg_restore: [archiver (db)] could not execute query: FEHLER: Relation »auxdata« existiert bereits Command was: CREATE TABLE auxdata ( x integer ); pg_restore: table auxdata could not be created, will not restore its data pg_restore: creating TABLE userdata pg_restore: restoring data for table "userdata" pg_restore: setting owner and privileges for SCHEMA public pg_restore: setting owner and privileges for COMMENT SCHEMA public pg_restore: setting owner and privileges for ACL public pg_restore: setting owner and privileges for TABLE auxdata pg_restore: setting owner and privileges for TABLE userdata WARNING: errors ignored on restore: 1 pg_restore failed with 1 === new/userdata: === 42 256 === new/auxdata: === -1 -2 ------------------- snip ------------------------ Thus, with the patch, auxdata is not restored (which produced the additional entries '1' and '2'). Thanks, Martin -- Martin Pitt http://www.piware.de Ubuntu Developer http://www.ubuntu.com Debian Developer http://www.debian.org In a world without walls and fences, who needs Windows and Gates?
test-pg_restore-existing.sh
Description: Bourne shell script
diff -ruN postgresql-8.1.3-old/src/bin/pg_dump/pg_backup_archiver.c postgresql-8.1.3/src/bin/pg_dump/pg_backup_archiver.c --- postgresql-8.1.3-old/src/bin/pg_dump/pg_backup_archiver.c 2006-02-05 21:58:57.000000000 +0100 +++ postgresql-8.1.3/src/bin/pg_dump/pg_backup_archiver.c 2006-02-19 14:20:36.000000000 +0100 @@ -268,6 +268,20 @@ _printTocEntry(AH, te, ropt, false, false); defnDumped = true; + /* If we could not create a table, ignore the respective TABLE DATA */ + if (AH->lastErrorTE == te && strcmp (te->desc, "TABLE") == 0) { + TocEntry *tes; + + ahlog (AH, 1, "table %s could not be created, will not restore its data\n", te->tag); + + for (tes = te->next; tes != AH->toc; tes = tes->next) { + if (strcmp (tes->desc, "TABLE DATA") == 0 && strcmp (tes->tag, te->tag) == 0) { + strcpy (tes->desc, "IGNOREDATA"); + break; + } + } + } + /* If we created a DB, connect to it... */ if (strcmp(te->desc, "DATABASE") == 0) { @@ -1876,6 +1889,10 @@ if (strcmp(te->desc, "ENCODING") == 0) return 0; + /* IGNOREDATA is a TABLE DATA which should not be restored */ + if (strcmp (te->desc, "IGNOREDATA") == 0) + return 0; + /* If it's an ACL, maybe ignore it */ if ((!include_acls || ropt->aclsSkip) && strcmp(te->desc, "ACL") == 0) return 0;
signature.asc
Description: Digital signature