[NUM_RELATION_STATS_ARGS] = {0}
};
-static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel,
- bool inplace);
+static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel);
/*
* Internal function for modifying statistics for a relation.
*/
static bool
-relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
+relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
{
bool result = true;
Oid reloid;
bool update_reltuples = false;
BlockNumber relallvisible = 0;
bool update_relallvisible = false;
+ HeapTuple ctup;
+ Form_pg_class pgcform;
+ int replaces[3] = {0};
+ Datum values[3] = {0};
+ bool nulls[3] = {0};
+ int nreplaces = 0;
if (!PG_ARGISNULL(RELPAGES_ARG))
{
*/
crel = table_open(RelationRelationId, RowExclusiveLock);
- if (inplace)
+ ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
+ if (!HeapTupleIsValid(ctup))
{
- HeapTuple ctup = NULL;
- ScanKeyData key[1];
- Form_pg_class pgcform;
- void *inplace_state = NULL;
- bool dirty = false;
-
- ScanKeyInit(&key[0], Anum_pg_class_oid, BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(reloid));
- systable_inplace_update_begin(crel, ClassOidIndexId, true, NULL, 1, key,
- &ctup, &inplace_state);
- if (!HeapTupleIsValid(ctup))
- elog(ERROR, "pg_class entry for relid %u vanished while updating statistics",
- reloid);
- pgcform = (Form_pg_class) GETSTRUCT(ctup);
-
- if (update_relpages && pgcform->relpages != relpages)
- {
- pgcform->relpages = relpages;
- dirty = true;
- }
- if (update_reltuples && pgcform->reltuples != reltuples)
- {
- pgcform->reltuples = reltuples;
- dirty = true;
- }
- if (update_relallvisible && pgcform->relallvisible != relallvisible)
- {
- pgcform->relallvisible = relallvisible;
- dirty = true;
- }
-
- if (dirty)
- systable_inplace_update_finish(inplace_state, ctup);
- else
- systable_inplace_update_cancel(inplace_state);
-
- heap_freetuple(ctup);
+ ereport(elevel,
+ (errcode(ERRCODE_OBJECT_IN_USE),
+ errmsg("pg_class entry for relid %u not found", reloid)));
+ table_close(crel, RowExclusiveLock);
+ return false;
}
- else
- {
- TupleDesc tupdesc = RelationGetDescr(crel);
- HeapTuple ctup;
- Form_pg_class pgcform;
- int replaces[3] = {0};
- Datum values[3] = {0};
- bool nulls[3] = {0};
- int nreplaces = 0;
-
- ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
- if (!HeapTupleIsValid(ctup))
- {
- ereport(elevel,
- (errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("pg_class entry for relid %u not found", reloid)));
- table_close(crel, RowExclusiveLock);
- return false;
- }
- pgcform = (Form_pg_class) GETSTRUCT(ctup);
- if (update_relpages && relpages != pgcform->relpages)
- {
- replaces[nreplaces] = Anum_pg_class_relpages;
- values[nreplaces] = UInt32GetDatum(relpages);
- nreplaces++;
- }
+ pgcform = (Form_pg_class) GETSTRUCT(ctup);
- if (update_reltuples && reltuples != pgcform->reltuples)
- {
- replaces[nreplaces] = Anum_pg_class_reltuples;
- values[nreplaces] = Float4GetDatum(reltuples);
- nreplaces++;
- }
+ if (update_relpages && relpages != pgcform->relpages)
+ {
+ replaces[nreplaces] = Anum_pg_class_relpages;
+ values[nreplaces] = UInt32GetDatum(relpages);
+ nreplaces++;
+ }
- if (update_relallvisible && relallvisible != pgcform->relallvisible)
- {
- replaces[nreplaces] = Anum_pg_class_relallvisible;
- values[nreplaces] = UInt32GetDatum(relallvisible);
- nreplaces++;
- }
+ if (update_reltuples && reltuples != pgcform->reltuples)
+ {
+ replaces[nreplaces] = Anum_pg_class_reltuples;
+ values[nreplaces] = Float4GetDatum(reltuples);
+ nreplaces++;
+ }
- if (nreplaces > 0)
- {
- HeapTuple newtup;
+ if (update_relallvisible && relallvisible != pgcform->relallvisible)
+ {
+ replaces[nreplaces] = Anum_pg_class_relallvisible;
+ values[nreplaces] = UInt32GetDatum(relallvisible);
+ nreplaces++;
+ }
- newtup = heap_modify_tuple_by_cols(ctup, tupdesc, nreplaces,
- replaces, values, nulls);
- CatalogTupleUpdate(crel, &newtup->t_self, newtup);
- heap_freetuple(newtup);
- }
+ if (nreplaces > 0)
+ {
+ TupleDesc tupdesc = RelationGetDescr(crel);
+ HeapTuple newtup;
- ReleaseSysCache(ctup);
+ newtup = heap_modify_tuple_by_cols(ctup, tupdesc, nreplaces,
+ replaces, values, nulls);
+ CatalogTupleUpdate(crel, &newtup->t_self, newtup);
+ heap_freetuple(newtup);
}
+ ReleaseSysCache(ctup);
+
/* release the lock, consistent with vac_update_relstats() */
table_close(crel, RowExclusiveLock);
Datum
pg_set_relation_stats(PG_FUNCTION_ARGS)
{
- relation_statistics_update(fcinfo, ERROR, false);
+ relation_statistics_update(fcinfo, ERROR);
PG_RETURN_VOID();
}
newfcinfo->args[3].value = UInt32GetDatum(0);
newfcinfo->args[3].isnull = false;
- relation_statistics_update(newfcinfo, ERROR, false);
+ relation_statistics_update(newfcinfo, ERROR);
PG_RETURN_VOID();
}
relarginfo, WARNING))
result = false;
- if (!relation_statistics_update(positional_fcinfo, WARNING, true))
+ if (!relation_statistics_update(positional_fcinfo, WARNING))
result = false;
PG_RETURN_BOOL(result);
18 | 401 | 5
(1 row)
--- test MVCC behavior: changes do not persist after abort (in contrast
--- to pg_restore_relation_stats(), which uses in-place updates).
-BEGIN;
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => NULL::integer,
- reltuples => 4000.0::real,
- relallvisible => 4::integer);
- pg_set_relation_stats
------------------------
-
-(1 row)
-
-ABORT;
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible
-----------+-----------+---------------
- 18 | 401 | 5
-(1 row)
-
-BEGIN;
-SELECT
- pg_catalog.pg_clear_relation_stats(
- 'stats_import.test'::regclass);
- pg_clear_relation_stats
--------------------------
-
-(1 row)
-
-ABORT;
SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
(1 row)
-- ok: just relpages
-SELECT pg_restore_relation_stats(
- 'relation', 'stats_import.test'::regclass,
- 'version', 150000::integer,
- 'relpages', '15'::integer);
- pg_restore_relation_stats
----------------------------
- t
-(1 row)
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible
-----------+-----------+---------------
- 15 | 400 | 4
-(1 row)
-
--- test non-MVCC behavior: new value should persist after abort
-BEGIN;
SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass,
'version', 150000::integer,
t
(1 row)
-ABORT;
SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
--- test MVCC behavior: changes do not persist after abort (in contrast
--- to pg_restore_relation_stats(), which uses in-place updates).
-BEGIN;
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => NULL::integer,
- reltuples => 4000.0::real,
- relallvisible => 4::integer);
-ABORT;
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
-BEGIN;
-SELECT
- pg_catalog.pg_clear_relation_stats(
- 'stats_import.test'::regclass);
-ABORT;
-
SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
WHERE oid = 'stats_import.test'::regclass;
-- ok: just relpages
-SELECT pg_restore_relation_stats(
- 'relation', 'stats_import.test'::regclass,
- 'version', 150000::integer,
- 'relpages', '15'::integer);
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
--- test non-MVCC behavior: new value should persist after abort
-BEGIN;
SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass,
'version', 150000::integer,
'relpages', '16'::integer);
-ABORT;
SELECT relpages, reltuples, relallvisible
FROM pg_class