|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.198 2002/09/2219:42:50 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.199 2002/09/2223:03:58 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *
|
14 | 14 | * INTERFACE ROUTINES
|
@@ -1168,13 +1168,8 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
|
1168 | 1168 | }
|
1169 | 1169 |
|
1170 | 1170 | if (!HeapTupleIsValid(tuple))
|
1171 |
| -{ |
1172 |
| -if (pg_class_scan) |
1173 |
| -heap_endscan(pg_class_scan); |
1174 |
| -heap_close(pg_class,RowExclusiveLock); |
1175 | 1171 | elog(ERROR,"setRelhasindex: cannot find relation %u in pg_class",
|
1176 | 1172 | relid);
|
1177 |
| -} |
1178 | 1173 |
|
1179 | 1174 | /*
|
1180 | 1175 | * Update fields in the pg_class tuple.
|
@@ -1319,11 +1314,7 @@ UpdateStats(Oid relid, double reltuples)
|
1319 | 1314 | HeapTupletuple;
|
1320 | 1315 | HeapTuplenewtup;
|
1321 | 1316 | BlockNumberrelpages;
|
1322 |
| -inti; |
1323 | 1317 | Form_pg_classrd_rel;
|
1324 |
| -Datumvalues[Natts_pg_class]; |
1325 |
| -charnulls[Natts_pg_class]; |
1326 |
| -charreplace[Natts_pg_class]; |
1327 | 1318 | HeapScanDescpg_class_scan=NULL;
|
1328 | 1319 | boolin_place_upd;
|
1329 | 1320 |
|
@@ -1375,13 +1366,8 @@ UpdateStats(Oid relid, double reltuples)
|
1375 | 1366 | }
|
1376 | 1367 |
|
1377 | 1368 | if (!HeapTupleIsValid(tuple))
|
1378 |
| -{ |
1379 |
| -if (pg_class_scan) |
1380 |
| -heap_endscan(pg_class_scan); |
1381 |
| -heap_close(pg_class,RowExclusiveLock); |
1382 | 1369 | elog(ERROR,"UpdateStats: cannot find relation %u in pg_class",
|
1383 | 1370 | relid);
|
1384 |
| -} |
1385 | 1371 |
|
1386 | 1372 | /*
|
1387 | 1373 | * Figure values to insert.
|
@@ -1417,57 +1403,57 @@ UpdateStats(Oid relid, double reltuples)
|
1417 | 1403 | }
|
1418 | 1404 |
|
1419 | 1405 | /*
|
1420 |
| - * We shouldn't have to do this, but we do... Modify the reldesc in |
1421 |
| - * place with the new values so that the cache contains the latest |
1422 |
| - * copy. |
| 1406 | + * Update statistics in pg_class, if they changed. (Avoiding an |
| 1407 | + * unnecessary update is not just a tiny performance improvement; |
| 1408 | + * it also reduces the window wherein concurrent CREATE INDEX commands |
| 1409 | + * may conflict.) |
1423 | 1410 | */
|
1424 |
| -whichRel->rd_rel->relpages= (int32)relpages; |
1425 |
| -whichRel->rd_rel->reltuples=reltuples; |
| 1411 | +rd_rel= (Form_pg_class)GETSTRUCT(tuple); |
1426 | 1412 |
|
1427 |
| -/* |
1428 |
| - * Update statistics in pg_class. |
1429 |
| - */ |
1430 |
| -if (in_place_upd) |
| 1413 | +if (rd_rel->relpages!= (int32)relpages|| |
| 1414 | +rd_rel->reltuples!= (float4)reltuples) |
1431 | 1415 | {
|
1432 |
| -/* |
1433 |
| - * At bootstrap time, we don't need to worry about concurrency or |
1434 |
| - * visibility of changes, so we cheat.Also cheat if REINDEX. |
1435 |
| - */ |
1436 |
| -rd_rel= (Form_pg_class)GETSTRUCT(tuple); |
1437 |
| -LockBuffer(pg_class_scan->rs_cbuf,BUFFER_LOCK_EXCLUSIVE); |
1438 |
| -rd_rel->relpages= (int32)relpages; |
1439 |
| -rd_rel->reltuples=reltuples; |
1440 |
| -LockBuffer(pg_class_scan->rs_cbuf,BUFFER_LOCK_UNLOCK); |
1441 |
| -WriteNoReleaseBuffer(pg_class_scan->rs_cbuf); |
1442 |
| -if (!IsBootstrapProcessingMode()) |
1443 |
| -CacheInvalidateHeapTuple(pg_class,tuple); |
1444 |
| -} |
1445 |
| -else |
1446 |
| -{ |
1447 |
| -/* During normal processing, must work harder. */ |
1448 |
| - |
1449 |
| -for (i=0;i<Natts_pg_class;i++) |
| 1416 | +if (in_place_upd) |
1450 | 1417 | {
|
1451 |
| -nulls[i]=' '; |
1452 |
| -replace[i]=' '; |
1453 |
| -values[i]= (Datum)NULL; |
| 1418 | +/* |
| 1419 | + * At bootstrap time, we don't need to worry about concurrency or |
| 1420 | + * visibility of changes, so we cheat.Also cheat if REINDEX. |
| 1421 | + */ |
| 1422 | +LockBuffer(pg_class_scan->rs_cbuf,BUFFER_LOCK_EXCLUSIVE); |
| 1423 | +rd_rel->relpages= (int32)relpages; |
| 1424 | +rd_rel->reltuples= (float4)reltuples; |
| 1425 | +LockBuffer(pg_class_scan->rs_cbuf,BUFFER_LOCK_UNLOCK); |
| 1426 | +WriteNoReleaseBuffer(pg_class_scan->rs_cbuf); |
| 1427 | +if (!IsBootstrapProcessingMode()) |
| 1428 | +CacheInvalidateHeapTuple(pg_class,tuple); |
| 1429 | +} |
| 1430 | +else |
| 1431 | +{ |
| 1432 | +/* During normal processing, must work harder. */ |
| 1433 | +newtup=heap_copytuple(tuple); |
| 1434 | +rd_rel= (Form_pg_class)GETSTRUCT(newtup); |
| 1435 | +rd_rel->relpages= (int32)relpages; |
| 1436 | +rd_rel->reltuples= (float4)reltuples; |
| 1437 | +simple_heap_update(pg_class,&tuple->t_self,newtup); |
| 1438 | +CatalogUpdateIndexes(pg_class,newtup); |
| 1439 | +heap_freetuple(newtup); |
1454 | 1440 | }
|
1455 |
| - |
1456 |
| -replace[Anum_pg_class_relpages-1]='r'; |
1457 |
| -values[Anum_pg_class_relpages-1]=Int32GetDatum((int32)relpages); |
1458 |
| -replace[Anum_pg_class_reltuples-1]='r'; |
1459 |
| -values[Anum_pg_class_reltuples-1]=Float4GetDatum((float4)reltuples); |
1460 |
| -newtup=heap_modifytuple(tuple,pg_class,values,nulls,replace); |
1461 |
| -simple_heap_update(pg_class,&tuple->t_self,newtup); |
1462 |
| -CatalogUpdateIndexes(pg_class,newtup); |
1463 |
| -heap_freetuple(newtup); |
1464 | 1441 | }
|
1465 | 1442 |
|
1466 | 1443 | if (!pg_class_scan)
|
1467 | 1444 | heap_freetuple(tuple);
|
1468 | 1445 | else
|
1469 | 1446 | heap_endscan(pg_class_scan);
|
1470 | 1447 |
|
| 1448 | +/* |
| 1449 | + * We shouldn't have to do this, but we do... Modify the reldesc in |
| 1450 | + * place with the new values so that the cache contains the latest |
| 1451 | + * copy. (XXX is this really still necessary? The relcache will get |
| 1452 | + * fixed at next CommandCounterIncrement, so why bother here?) |
| 1453 | + */ |
| 1454 | +whichRel->rd_rel->relpages= (int32)relpages; |
| 1455 | +whichRel->rd_rel->reltuples= (float4)reltuples; |
| 1456 | + |
1471 | 1457 | heap_close(pg_class,RowExclusiveLock);
|
1472 | 1458 | relation_close(whichRel,NoLock);
|
1473 | 1459 | }
|
|