|
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(Oid myrelid, bool recurse, bool setOid) |
| 2391 | +{ |
| 2392 | + Relation rel; |
| 2393 | + Relation class_rel; |
| 2394 | + HeapTuple tuple; |
| 2395 | + Form_pg_class tuple_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 | + Oid childrelid = 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 | + HeapTuple atttup; |
| 2477 | + Relation attrel; |
| 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
|
|
0 commit comments