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
/*
0 commit comments