15
15
*
16
16
*
17
17
* 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 $
19
19
*
20
20
*-------------------------------------------------------------------------
21
21
*/
@@ -47,7 +47,7 @@ static char *modulename = gettext_noop("archiver");
47
47
48
48
static ArchiveHandle * _allocAH (const char * FileSpec ,const ArchiveFormat fmt ,
49
49
const int compression ,ArchiveMode mode );
50
- static char * _getObjectFromDropStmt ( const char * dropStmt , const char * type );
50
+ static void _getObjectDescription ( PQExpBuffer buf , TocEntry * te );
51
51
static void _printTocEntry (ArchiveHandle * AH ,TocEntry * te ,RestoreOptions * ropt ,bool isData ,bool acl_pass );
52
52
53
53
@@ -2363,64 +2363,78 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace)
2363
2363
destroyPQExpBuffer (qry );
2364
2364
}
2365
2365
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.
2370
2374
*/
2371
- static char *
2372
- _getObjectFromDropStmt ( const char * dropStmt , const char * type )
2375
+ static void
2376
+ _getObjectDescription ( PQExpBuffer buf , TocEntry * te )
2373
2377
{
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 ;
2379
2379
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" ;
2386
2384
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" ;
2389
2388
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 )
2395
2395
{
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 ;
2398
2399
}
2399
2400
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 )
2405
2404
{
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 ;
2411
2407
}
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 )
2413
2417
{
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 );
2415
2431
2416
- buf = malloc (len );
2417
- snprintf (buf ,len ,"TABLE %s" ,first + 9 );
2418
2432
free (first );
2433
+ return ;
2419
2434
}
2420
- else
2421
- buf = first ;
2422
2435
2423
- return buf ;
2436
+ write_msg (modulename ,"WARNING: don't know how to set owner for object type %s\n" ,
2437
+ type );
2424
2438
}
2425
2439
2426
2440
static void
@@ -2497,13 +2511,14 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2497
2511
/*
2498
2512
* Actually print the definition.
2499
2513
*
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
2502
2517
* no other good way ...
2503
2518
*/
2504
- if (AH -> ropt && AH -> ropt -> noOwner && strcmp (te -> desc ,"SCHEMA" )== 0 )
2519
+ if (ropt -> noOwner && strcmp (te -> desc ,"SCHEMA" )== 0 )
2505
2520
{
2506
- ahprintf (AH ,"CREATE SCHEMA %s;\n\n\n" ,te -> tag );
2521
+ ahprintf (AH ,"CREATE SCHEMA %s;\n\n\n" ,fmtId ( te -> tag ) );
2507
2522
}
2508
2523
else
2509
2524
{
@@ -2513,29 +2528,51 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2513
2528
2514
2529
/*
2515
2530
* 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.
2520
2534
*/
2521
2535
if (!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
+ }
2539
2576
}
2540
2577
2541
2578
/*