1515 *
1616 *
1717 * IDENTIFICATION
18- *$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.100 2004/11/06 19:36:01 tgl Exp $
18+ *$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.101 2005/01/11 05:14:10 tgl Exp $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
@@ -47,7 +47,7 @@ static char *modulename = gettext_noop("archiver");
4747
4848static ArchiveHandle * _allocAH (const char * FileSpec ,const ArchiveFormat fmt ,
4949const int compression ,ArchiveMode mode );
50- static char * _getObjectFromDropStmt ( const char * dropStmt , const char * type );
50+ static void _getObjectDescription ( PQExpBuffer buf , TocEntry * te );
5151static void _printTocEntry (ArchiveHandle * AH ,TocEntry * te ,RestoreOptions * ropt ,bool isData ,bool acl_pass );
5252
5353
@@ -2363,64 +2363,78 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace)
23632363destroyPQExpBuffer (qry );
23642364}
23652365
2366- /**
2367- * Parses the dropStmt part of a TOC entry and returns
2368- * a newly allocated string that is the object identifier
2369- * The caller must free the result.
2366+ /*
2367+ * Extract an object description for a TOC entry, and append it to buf.
2368+ *
2369+ * This is not quite as general as it may seem, since it really only
2370+ * handles constructing the right thing to put into ALTER ... OWNER TO.
2371+ *
2372+ * The whole thing is pretty grotty, but we are kind of stuck since the
2373+ * information used is all that's available in older dump files.
23702374 */
2371- static char *
2372- _getObjectFromDropStmt ( const char * dropStmt , const char * type )
2375+ static void
2376+ _getObjectDescription ( PQExpBuffer buf , TocEntry * te )
23732377{
2374- /* Chop "DROP" off the front and make a copy */
2375- char * first = strdup (dropStmt + 5 );
2376- char * last = first + strlen (first )- 1 ;/* Points to the last
2377- * real char in extract */
2378- char * buf = NULL ;
2378+ const char * type = te -> desc ;
23792379
2380- /*
2381- * Loop from the end of the string until last char is no longer '\n'
2382- * or ';'
2383- */
2384- while (last >=first && (* last == '\n' || * last == ';' ))
2385- last -- ;
2380+ /* Use ALTER TABLE for views and sequences */
2381+ if (strcmp (type ,"VIEW" )== 0 ||
2382+ strcmp (type ,"SEQUENCE" )== 0 )
2383+ type = "TABLE" ;
23862384
2387- /* Insert end of string one place after last */
2388- * (last + 1 )= '\0' ;
2385+ /* We assume CONSTRAINTs are always pkey/unique indexes */
2386+ if (strcmp (type ,"CONSTRAINT" )== 0 )
2387+ type = "INDEX" ;
23892388
2390- /*
2391- * Take off CASCADE if necessary. Only TYPEs seem to have this, but
2392- * may as well check for all
2393- */
2394- if ((last - first ) >=8 )
2389+ /* objects named by a schema and name */
2390+ if (strcmp (type ,"CONVERSION" )== 0 ||
2391+ strcmp (type ,"DOMAIN" )== 0 ||
2392+ strcmp (type ,"INDEX" )== 0 ||
2393+ strcmp (type ,"TABLE" )== 0 ||
2394+ strcmp (type ,"TYPE" )== 0 )
23952395{
2396- if (strcmp (last - 7 ," CASCADE" )== 0 )
2397- last -= 8 ;
2396+ appendPQExpBuffer (buf ,"%s %s" ,type ,fmtId (te -> namespace ));
2397+ appendPQExpBuffer (buf ,".%s" ,fmtId (te -> tag ));
2398+ return ;
23982399}
23992400
2400- /* Insert end of string one place after last */
2401- * (last + 1 )= '\0' ;
2402-
2403- /* Special case VIEWs and SEQUENCEs. They must use ALTER TABLE. */
2404- if (strcmp (type ,"VIEW" )== 0 && (last - first ) >=5 )
2401+ /* objects named by just a name */
2402+ if (strcmp (type ,"DATABASE" )== 0 ||
2403+ strcmp (type ,"SCHEMA" )== 0 )
24052404{
2406- int len = 6 + strlen (first + 5 )+ 1 ;
2407-
2408- buf = malloc (len );
2409- snprintf (buf ,len ,"TABLE %s" ,first + 5 );
2410- free (first );
2405+ appendPQExpBuffer (buf ,"%s %s" ,type ,fmtId (te -> tag ));
2406+ return ;
24112407}
2412- else if (strcmp (type ,"SEQUENCE" )== 0 && (last - first ) >=9 )
2408+
2409+ /*
2410+ * These object types require additional decoration. Fortunately,
2411+ * the information needed is exactly what's in the DROP command.
2412+ */
2413+ if (strcmp (type ,"AGGREGATE" )== 0 ||
2414+ strcmp (type ,"FUNCTION" )== 0 ||
2415+ strcmp (type ,"OPERATOR" )== 0 ||
2416+ strcmp (type ,"OPERATOR CLASS" )== 0 )
24132417{
2414- int len = 6 + strlen (first + 9 )+ 1 ;
2418+ /* Chop "DROP " off the front and make a modifiable copy */
2419+ char * first = strdup (te -> dropStmt + 5 );
2420+ char * last ;
2421+
2422+ /* point to last character in string */
2423+ last = first + strlen (first )- 1 ;
2424+
2425+ /* Strip off any ';' or '\n' at the end */
2426+ while (last >=first && (* last == '\n' || * last == ';' ))
2427+ last -- ;
2428+ * (last + 1 )= '\0' ;
2429+
2430+ appendPQExpBufferStr (buf ,first );
24152431
2416- buf = malloc (len );
2417- snprintf (buf ,len ,"TABLE %s" ,first + 9 );
24182432free (first );
2433+ return ;
24192434}
2420- else
2421- buf = first ;
24222435
2423- return buf ;
2436+ write_msg (modulename ,"WARNING: don't know how to set owner for object type %s\n" ,
2437+ type );
24242438}
24252439
24262440static void
@@ -2497,13 +2511,14 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
24972511/*
24982512 * Actually print the definition.
24992513 *
2500- * Really crude hack for suppressing AUTHORIZATION clause of CREATE
2501- * SCHEMA when --no-owner mode is selected. This is ugly, but I see
2514+ * Really crude hack for suppressing AUTHORIZATION clause that old
2515+ * pg_dump versions put into CREATE SCHEMA. We have to do this when
2516+ * --no-owner mode is selected. This is ugly, but I see
25022517 * no other good way ...
25032518 */
2504- if (AH -> ropt && AH -> ropt -> noOwner && strcmp (te -> desc ,"SCHEMA" )== 0 )
2519+ if (ropt -> noOwner && strcmp (te -> desc ,"SCHEMA" )== 0 )
25052520{
2506- ahprintf (AH ,"CREATE SCHEMA %s;\n\n\n" ,te -> tag );
2521+ ahprintf (AH ,"CREATE SCHEMA %s;\n\n\n" ,fmtId ( te -> tag ) );
25072522}
25082523else
25092524{
@@ -2513,29 +2528,51 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
25132528
25142529/*
25152530 * If we aren't using SET SESSION AUTH to determine ownership, we must
2516- * instead issue an ALTER OWNER command. Ugly, since we have to cons
2517- * one up based on the dropStmt. We don't need this for schemas
2518- * (since we use CREATE SCHEMA AUTHORIZATION instead), nor for some
2519- * other object types.
2531+ * instead issue an ALTER OWNER command. We assume that anything without
2532+ * a DROP command is not a separately ownable object. All the categories
2533+ * with DROP commands must appear in one list or the other.
25202534 */
25212535if (!ropt -> noOwner && !ropt -> use_setsessauth &&
2522- strlen (te -> owner )> 0 && strlen (te -> dropStmt )> 0 &&
2523- (strcmp (te -> desc ,"AGGREGATE" )== 0 ||
2524- strcmp (te -> desc ,"CONVERSION" )== 0 ||
2525- strcmp (te -> desc ,"DATABASE" )== 0 ||
2526- strcmp (te -> desc ,"DOMAIN" )== 0 ||
2527- strcmp (te -> desc ,"FUNCTION" )== 0 ||
2528- strcmp (te -> desc ,"OPERATOR" )== 0 ||
2529- strcmp (te -> desc ,"OPERATOR CLASS" )== 0 ||
2530- strcmp (te -> desc ,"TABLE" )== 0 ||
2531- strcmp (te -> desc ,"TYPE" )== 0 ||
2532- strcmp (te -> desc ,"VIEW" )== 0 ||
2533- strcmp (te -> desc ,"SEQUENCE" )== 0 ))
2534- {
2535- char * temp = _getObjectFromDropStmt (te -> dropStmt ,te -> desc );
2536-
2537- ahprintf (AH ,"ALTER %s OWNER TO %s;\n\n" ,temp ,fmtId (te -> owner ));
2538- free (temp );
2536+ strlen (te -> owner )> 0 && strlen (te -> dropStmt )> 0 )
2537+ {
2538+ if (strcmp (te -> desc ,"AGGREGATE" )== 0 ||
2539+ strcmp (te -> desc ,"CONSTRAINT" )== 0 ||
2540+ strcmp (te -> desc ,"CONVERSION" )== 0 ||
2541+ strcmp (te -> desc ,"DATABASE" )== 0 ||
2542+ strcmp (te -> desc ,"DOMAIN" )== 0 ||
2543+ strcmp (te -> desc ,"FUNCTION" )== 0 ||
2544+ strcmp (te -> desc ,"INDEX" )== 0 ||
2545+ strcmp (te -> desc ,"OPERATOR" )== 0 ||
2546+ strcmp (te -> desc ,"OPERATOR CLASS" )== 0 ||
2547+ strcmp (te -> desc ,"SCHEMA" )== 0 ||
2548+ strcmp (te -> desc ,"TABLE" )== 0 ||
2549+ strcmp (te -> desc ,"TYPE" )== 0 ||
2550+ strcmp (te -> desc ,"VIEW" )== 0 ||
2551+ strcmp (te -> desc ,"SEQUENCE" )== 0 )
2552+ {
2553+ PQExpBuffer temp = createPQExpBuffer ();
2554+
2555+ appendPQExpBuffer (temp ,"ALTER " );
2556+ _getObjectDescription (temp ,te );
2557+ appendPQExpBuffer (temp ," OWNER TO %s;" ,fmtId (te -> owner ));
2558+ ahprintf (AH ,"%s\n\n" ,temp -> data );
2559+ destroyPQExpBuffer (temp );
2560+ }
2561+ else if (strcmp (te -> desc ,"CAST" )== 0 ||
2562+ strcmp (te -> desc ,"CHECK CONSTRAINT" )== 0 ||
2563+ strcmp (te -> desc ,"DEFAULT" )== 0 ||
2564+ strcmp (te -> desc ,"FK CONSTRAINT" )== 0 ||
2565+ strcmp (te -> desc ,"PROCEDURAL LANGUAGE" )== 0 ||
2566+ strcmp (te -> desc ,"RULE" )== 0 ||
2567+ strcmp (te -> desc ,"TRIGGER" )== 0 )
2568+ {
2569+ /* these object types don't have separate owners */
2570+ }
2571+ else
2572+ {
2573+ write_msg (modulename ,"WARNING: don't know how to set owner for object type %s\n" ,
2574+ te -> desc );
2575+ }
25392576}
25402577
25412578/*