|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.66 2003/02/09 06:56:26 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.67 2003/02/13 05:19:59 momjian Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -2134,7 +2134,6 @@ AlterTableAlterColumnSetNotNull(Oid myrelid, bool recurse,
|
2134 | 2134 | heap_close(rel,NoLock);
|
2135 | 2135 | }
|
2136 | 2136 |
|
2137 |
| - |
2138 | 2137 | /*
|
2139 | 2138 | * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
|
2140 | 2139 | */
|
@@ -2384,6 +2383,122 @@ AlterTableAlterColumnFlags(Oid myrelid, bool recurse,
|
2384 | 2383 | heap_close(rel,NoLock);/* close rel, but keep lock! */
|
2385 | 2384 | }
|
2386 | 2385 |
|
| 2386 | +/* |
| 2387 | + * ALTER TABLE SET {WITHOUT} OIDS |
| 2388 | + */ |
| 2389 | +void |
| 2390 | +AlterTableAlterOids(Oidmyrelid,boolrecurse,boolsetOid) |
| 2391 | +{ |
| 2392 | +Relationrel; |
| 2393 | +Relationclass_rel; |
| 2394 | +HeapTupletuple; |
| 2395 | +Form_pg_classtuple_class; |
| 2396 | + |
| 2397 | +rel=heap_open(myrelid,AccessExclusiveLock); |
| 2398 | + |
| 2399 | +if (rel->rd_rel->relkind!=RELKIND_RELATION) |
| 2400 | +elog(ERROR,"ALTER TABLE: relation \"%s\" is not a table", |
| 2401 | +RelationGetRelationName(rel)); |
| 2402 | + |
| 2403 | +if (!allowSystemTableMods |
| 2404 | +&&IsSystemRelation(rel)) |
| 2405 | +elog(ERROR,"ALTER TABLE: relation \"%s\" is a system catalog", |
| 2406 | +RelationGetRelationName(rel)); |
| 2407 | + |
| 2408 | +if (!pg_class_ownercheck(myrelid,GetUserId())) |
| 2409 | +aclcheck_error(ACLCHECK_NOT_OWNER,RelationGetRelationName(rel)); |
| 2410 | + |
| 2411 | + |
| 2412 | +/* Get its pg_class tuple, too */ |
| 2413 | +class_rel=heap_openr(RelationRelationName,RowExclusiveLock); |
| 2414 | + |
| 2415 | +tuple=SearchSysCacheCopy(RELOID, |
| 2416 | +ObjectIdGetDatum(myrelid), |
| 2417 | +0,0,0); |
| 2418 | +if (!HeapTupleIsValid(tuple)) |
| 2419 | +elog(ERROR,"ALTER TABLE: relation %u not found",myrelid); |
| 2420 | +tuple_class= (Form_pg_class)GETSTRUCT(tuple); |
| 2421 | + |
| 2422 | +/* Can we change the ownership of this tuple? */ |
| 2423 | +CheckTupleType(tuple_class); |
| 2424 | + |
| 2425 | +/* |
| 2426 | + * Okay, this is a valid tuple: check it's hasoids flag |
| 2427 | + * to see if we actually need to change anything |
| 2428 | + */ |
| 2429 | +if (tuple_class->relhasoids==setOid) |
| 2430 | +elog(ERROR,"ALTER TABLE: Table is already %s", |
| 2431 | +setOid ?"WITH OIDS" :"WITHOUT OIDS"); |
| 2432 | + |
| 2433 | +/* |
| 2434 | + * Propagate to children if desired |
| 2435 | + */ |
| 2436 | +if (recurse) |
| 2437 | +{ |
| 2438 | +List*child, |
| 2439 | +*children; |
| 2440 | + |
| 2441 | +/* this routine is actually in the planner */ |
| 2442 | +children=find_all_inheritors(myrelid); |
| 2443 | + |
| 2444 | +/* |
| 2445 | + * find_all_inheritors does the recursive search of the |
| 2446 | + * inheritance hierarchy, so all we have to do is process all of |
| 2447 | + * the relids in the list that it returns. |
| 2448 | + */ |
| 2449 | +foreach(child,children) |
| 2450 | +{ |
| 2451 | +Oidchildrelid=lfirsti(child); |
| 2452 | + |
| 2453 | +if (childrelid==myrelid) |
| 2454 | +continue; |
| 2455 | + |
| 2456 | +AlterTableAlterOids(childrelid, false,setOid); |
| 2457 | +} |
| 2458 | +} |
| 2459 | + |
| 2460 | + |
| 2461 | +tuple_class->relhasoids=setOid; |
| 2462 | +simple_heap_update(class_rel,&tuple->t_self,tuple); |
| 2463 | + |
| 2464 | +/* Keep the catalog indexes up to date */ |
| 2465 | +CatalogUpdateIndexes(class_rel,tuple); |
| 2466 | + |
| 2467 | + |
| 2468 | + |
| 2469 | +if (setOid) |
| 2470 | +/* |
| 2471 | + * TODO: Generate the now required OID pg_attribute entry |
| 2472 | + */ |
| 2473 | +elog(ERROR,"ALTER TABLE WITH OIDS is unsupported"); |
| 2474 | +else |
| 2475 | +{ |
| 2476 | +HeapTupleatttup; |
| 2477 | +Relationattrel; |
| 2478 | + |
| 2479 | +/* Add / Remove the oid record from pg_attribute */ |
| 2480 | +attrel=heap_open(RelOid_pg_attribute,RowExclusiveLock); |
| 2481 | + |
| 2482 | +/* |
| 2483 | + * Oids are being removed from the relation, so we need |
| 2484 | + * to remove the oid pg_attribute record relating. |
| 2485 | + */ |
| 2486 | +atttup=SearchSysCache(ATTNUM, |
| 2487 | +ObjectIdGetDatum(myrelid), |
| 2488 | +ObjectIdAttributeNumber,0,0); |
| 2489 | +if (!HeapTupleIsValid(atttup)) |
| 2490 | +elog(ERROR,"ALTER TABLE: relation %u doesn't have an Oid column to remove",myrelid); |
| 2491 | + |
| 2492 | +simple_heap_delete(attrel,&atttup->t_self); |
| 2493 | + |
| 2494 | +ReleaseSysCache(atttup); |
| 2495 | + |
| 2496 | +heap_close(attrel,NoLock);/* close rel, but keep lock! */ |
| 2497 | +} |
| 2498 | + |
| 2499 | +heap_close(rel,NoLock);/* close rel, but keep lock! */ |
| 2500 | +heap_close(class_rel,NoLock);/* close rel, but keep lock! */ |
| 2501 | +} |
2387 | 2502 |
|
2388 | 2503 | /*
|
2389 | 2504 | * ALTER TABLE DROP COLUMN
|
|