mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-11-27 07:21:09 +08:00
Do not access indclass through Form_pg_index
Normally, accessing variable-length members of catalog structures past the first one doesn't work at all. Here, it happened to work because indnatts was checked to be 1, and so the defined FormData_pg_index layout, using int2vector[1] and oidvector[1] for variable-length arrays, happened to match the actual memory layout. But it's a very fragile assumption, and it's not in a performance-critical path, so code it properly using heap_getattr() instead. bug analysis by Tom Lane
This commit is contained in:
parent
eb6af016fc
commit
8a3f745f16
17
src/backend/utils/cache/relcache.c
vendored
17
src/backend/utils/cache/relcache.c
vendored
@ -3351,15 +3351,30 @@ RelationGetIndexList(Relation relation)
|
||||
while (HeapTupleIsValid(htup = systable_getnext(indscan)))
|
||||
{
|
||||
Form_pg_index index = (Form_pg_index) GETSTRUCT(htup);
|
||||
Datum indclassDatum;
|
||||
oidvector *indclass;
|
||||
bool isnull;
|
||||
|
||||
/* Add index's OID to result list in the proper order */
|
||||
result = insert_ordered_oid(result, index->indexrelid);
|
||||
|
||||
/*
|
||||
* indclass cannot be referenced directly through the C struct, because
|
||||
* it comes after the variable-width indkey field. Must extract the
|
||||
* datum the hard way...
|
||||
*/
|
||||
indclassDatum = heap_getattr(htup,
|
||||
Anum_pg_index_indclass,
|
||||
GetPgIndexDescriptor(),
|
||||
&isnull);
|
||||
Assert(!isnull);
|
||||
indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||
|
||||
/* Check to see if it is a unique, non-partial btree index on OID */
|
||||
if (index->indnatts == 1 &&
|
||||
index->indisunique && index->indimmediate &&
|
||||
index->indkey.values[0] == ObjectIdAttributeNumber &&
|
||||
index->indclass.values[0] == OID_BTREE_OPS_OID &&
|
||||
indclass->values[0] == OID_BTREE_OPS_OID &&
|
||||
heap_attisnull(htup, Anum_pg_index_indpred))
|
||||
oidIndex = index->indexrelid;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user