postgresql/src/backend/catalog/indexing.c

176 lines
5.7 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* indexing.c
* This file contains routines to support indices defined on system
* catalogs.
*
2002-06-20 22:29:54 +02:00
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.99 2002/07/22 20:23:19 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
2000-06-15 05:33:12 +02:00
#include "catalog/pg_index.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
/*
Clean up various to-do items associated with system indexes: pg_database now has unique indexes on oid and on datname. pg_shadow now has unique indexes on usename and on usesysid. pg_am now has unique index on oid. pg_opclass now has unique index on oid. pg_amproc now has unique index on amid+amopclaid+amprocnum. Remove pg_rewrite's unnecessary index on oid, delete unused RULEOID syscache. Remove index on pg_listener and associated syscache for performance reasons (caching rows that are certain to change before you need 'em again is rather pointless). Change pg_attrdef's nonunique index on adrelid into a unique index on adrelid+adnum. Fix various incorrect settings of pg_class.relisshared, make that the primary reference point for whether a relation is shared or not. IsSharedSystemRelationName() is now only consulted to initialize relisshared during initial creation of tables and indexes. In theory we might now support shared user relations, though it's not clear how one would get entries for them into pg_class &etc of multiple databases. Fix recently reported bug that pg_attribute rows created for an index all have the same OID. (Proof that non-unique OID doesn't matter unless it's actually used to do lookups ;-)) There's no need to treat pg_trigger, pg_attrdef, pg_relcheck as bootstrap relations. Convert them into plain system catalogs without hardwired entries in pg_class and friends. Unify global.bki and template1.bki into a single init script postgres.bki, since the alleged distinction between them was misleading and pointless. Not to mention that it didn't work for setting up indexes on shared system relations. Rationalize locking of pg_shadow, pg_group, pg_attrdef (no need to use AccessExclusiveLock where ExclusiveLock or even RowExclusiveLock will do). Also, hold locks until transaction commit where necessary.
2001-06-12 07:55:50 +02:00
* Names of indices for each system catalog.
*/
char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
{AggregateFnoidIndex};
char *Name_pg_am_indices[Num_pg_am_indices] =
Clean up various to-do items associated with system indexes: pg_database now has unique indexes on oid and on datname. pg_shadow now has unique indexes on usename and on usesysid. pg_am now has unique index on oid. pg_opclass now has unique index on oid. pg_amproc now has unique index on amid+amopclaid+amprocnum. Remove pg_rewrite's unnecessary index on oid, delete unused RULEOID syscache. Remove index on pg_listener and associated syscache for performance reasons (caching rows that are certain to change before you need 'em again is rather pointless). Change pg_attrdef's nonunique index on adrelid into a unique index on adrelid+adnum. Fix various incorrect settings of pg_class.relisshared, make that the primary reference point for whether a relation is shared or not. IsSharedSystemRelationName() is now only consulted to initialize relisshared during initial creation of tables and indexes. In theory we might now support shared user relations, though it's not clear how one would get entries for them into pg_class &etc of multiple databases. Fix recently reported bug that pg_attribute rows created for an index all have the same OID. (Proof that non-unique OID doesn't matter unless it's actually used to do lookups ;-)) There's no need to treat pg_trigger, pg_attrdef, pg_relcheck as bootstrap relations. Convert them into plain system catalogs without hardwired entries in pg_class and friends. Unify global.bki and template1.bki into a single init script postgres.bki, since the alleged distinction between them was misleading and pointless. Not to mention that it didn't work for setting up indexes on shared system relations. Rationalize locking of pg_shadow, pg_group, pg_attrdef (no need to use AccessExclusiveLock where ExclusiveLock or even RowExclusiveLock will do). Also, hold locks until transaction commit where necessary.
2001-06-12 07:55:50 +02:00
{AmNameIndex, AmOidIndex};
char *Name_pg_amop_indices[Num_pg_amop_indices] =
{AccessMethodOperatorIndex, AccessMethodStrategyIndex};
Clean up various to-do items associated with system indexes: pg_database now has unique indexes on oid and on datname. pg_shadow now has unique indexes on usename and on usesysid. pg_am now has unique index on oid. pg_opclass now has unique index on oid. pg_amproc now has unique index on amid+amopclaid+amprocnum. Remove pg_rewrite's unnecessary index on oid, delete unused RULEOID syscache. Remove index on pg_listener and associated syscache for performance reasons (caching rows that are certain to change before you need 'em again is rather pointless). Change pg_attrdef's nonunique index on adrelid into a unique index on adrelid+adnum. Fix various incorrect settings of pg_class.relisshared, make that the primary reference point for whether a relation is shared or not. IsSharedSystemRelationName() is now only consulted to initialize relisshared during initial creation of tables and indexes. In theory we might now support shared user relations, though it's not clear how one would get entries for them into pg_class &etc of multiple databases. Fix recently reported bug that pg_attribute rows created for an index all have the same OID. (Proof that non-unique OID doesn't matter unless it's actually used to do lookups ;-)) There's no need to treat pg_trigger, pg_attrdef, pg_relcheck as bootstrap relations. Convert them into plain system catalogs without hardwired entries in pg_class and friends. Unify global.bki and template1.bki into a single init script postgres.bki, since the alleged distinction between them was misleading and pointless. Not to mention that it didn't work for setting up indexes on shared system relations. Rationalize locking of pg_shadow, pg_group, pg_attrdef (no need to use AccessExclusiveLock where ExclusiveLock or even RowExclusiveLock will do). Also, hold locks until transaction commit where necessary.
2001-06-12 07:55:50 +02:00
char *Name_pg_amproc_indices[Num_pg_amproc_indices] =
{AccessMethodProcedureIndex};
char *Name_pg_attr_indices[Num_pg_attr_indices] =
{AttributeRelidNameIndex, AttributeRelidNumIndex};
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
{AttrDefaultIndex, AttrDefaultOidIndex};
char *Name_pg_cast_indices[Num_pg_cast_indices] =
{CastOidIndex, CastSourceTargetIndex};
char *Name_pg_class_indices[Num_pg_class_indices] =
{ClassNameNspIndex, ClassOidIndex};
char *Name_pg_constraint_indices[Num_pg_constraint_indices] =
{ConstraintNameNspIndex, ConstraintOidIndex, ConstraintRelidIndex};
char *Name_pg_conversion_indices[Num_pg_conversion_indices] =
{ConversionDefaultIndex, ConversionNameNspIndex, ConversionOidIndex};
Clean up various to-do items associated with system indexes: pg_database now has unique indexes on oid and on datname. pg_shadow now has unique indexes on usename and on usesysid. pg_am now has unique index on oid. pg_opclass now has unique index on oid. pg_amproc now has unique index on amid+amopclaid+amprocnum. Remove pg_rewrite's unnecessary index on oid, delete unused RULEOID syscache. Remove index on pg_listener and associated syscache for performance reasons (caching rows that are certain to change before you need 'em again is rather pointless). Change pg_attrdef's nonunique index on adrelid into a unique index on adrelid+adnum. Fix various incorrect settings of pg_class.relisshared, make that the primary reference point for whether a relation is shared or not. IsSharedSystemRelationName() is now only consulted to initialize relisshared during initial creation of tables and indexes. In theory we might now support shared user relations, though it's not clear how one would get entries for them into pg_class &etc of multiple databases. Fix recently reported bug that pg_attribute rows created for an index all have the same OID. (Proof that non-unique OID doesn't matter unless it's actually used to do lookups ;-)) There's no need to treat pg_trigger, pg_attrdef, pg_relcheck as bootstrap relations. Convert them into plain system catalogs without hardwired entries in pg_class and friends. Unify global.bki and template1.bki into a single init script postgres.bki, since the alleged distinction between them was misleading and pointless. Not to mention that it didn't work for setting up indexes on shared system relations. Rationalize locking of pg_shadow, pg_group, pg_attrdef (no need to use AccessExclusiveLock where ExclusiveLock or even RowExclusiveLock will do). Also, hold locks until transaction commit where necessary.
2001-06-12 07:55:50 +02:00
char *Name_pg_database_indices[Num_pg_database_indices] =
{DatabaseNameIndex, DatabaseOidIndex};
char *Name_pg_depend_indices[Num_pg_depend_indices] =
{DependDependerIndex, DependReferenceIndex};
char *Name_pg_group_indices[Num_pg_group_indices] =
{GroupNameIndex, GroupSysidIndex};
char *Name_pg_index_indices[Num_pg_index_indices] =
{IndexRelidIndex, IndexIndrelidIndex};
char *Name_pg_inherits_indices[Num_pg_inherits_indices] =
{InheritsRelidSeqnoIndex};
char *Name_pg_language_indices[Num_pg_language_indices] =
{LanguageOidIndex, LanguageNameIndex};
char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] =
{LargeObjectLOidPNIndex};
char *Name_pg_namespace_indices[Num_pg_namespace_indices] =
{NamespaceNameIndex, NamespaceOidIndex};
char *Name_pg_opclass_indices[Num_pg_opclass_indices] =
{OpclassAmNameNspIndex, OpclassOidIndex};
char *Name_pg_operator_indices[Num_pg_operator_indices] =
{OperatorOidIndex, OperatorNameNspIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] =
{ProcedureOidIndex, ProcedureNameNspIndex};
char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
{RewriteOidIndex, RewriteRelRulenameIndex};
char *Name_pg_shadow_indices[Num_pg_shadow_indices] =
{ShadowNameIndex, ShadowSysidIndex};
1999-11-25 01:15:57 +01:00
char *Name_pg_statistic_indices[Num_pg_statistic_indices] =
{StatisticRelidAttnumIndex};
char *Name_pg_trigger_indices[Num_pg_trigger_indices] =
{TriggerRelidNameIndex, TriggerConstrNameIndex, TriggerConstrRelidIndex, TriggerOidIndex};
char *Name_pg_type_indices[Num_pg_type_indices] =
{TypeNameNspIndex, TypeOidIndex};
char *Name_pg_description_indices[Num_pg_description_indices] =
{DescriptionObjIndex};
/*
* Changes (appends) to catalogs can and do happen at various places
* throughout the code. We need a generic routine that will open all of
* the indices defined on a given catalog and return the relation descriptors
* associated with them.
*/
void
1998-09-01 05:29:17 +02:00
CatalogOpenIndices(int nIndices, char **names, Relation *idescs)
{
int i;
2000-02-18 10:30:20 +01:00
if (IsIgnoringSystemIndexes())
return;
for (i = 0; i < nIndices; i++)
idescs[i] = index_openr(names[i]);
}
/*
* This is the inverse routine to CatalogOpenIndices()
*/
void
CatalogCloseIndices(int nIndices, Relation *idescs)
{
int i;
2000-02-18 10:30:20 +01:00
if (IsIgnoringSystemIndexes())
return;
for (i = 0; i < nIndices; i++)
index_close(idescs[i]);
}
/*
* For the same reasons outlined above for CatalogOpenIndices(), we need a
* routine that takes a new catalog tuple and inserts an associated index
* tuple into each catalog index.
*
* NOTE: since this routine looks up all the pg_index data on each call,
* it's relatively inefficient for inserting a large number of tuples into
* the same catalog. We use it only for inserting one or a few tuples
2001-03-22 05:01:46 +01:00
* in a given command. See ExecOpenIndices() and related routines if you
* are inserting tuples in bulk.
*
* NOTE: we do not bother to handle partial indices. Nor do we try to
* be efficient for functional indices (the code should work for them,
* but may leak memory intraquery). This should be OK for system catalogs,
* but don't use this routine for user tables!
*/
void
CatalogIndexInsert(Relation *idescs,
int nIndices,
Relation heapRelation,
HeapTuple heapTuple)
{
TupleDesc heapDescriptor;
1998-09-03 01:05:37 +02:00
Datum datum[INDEX_MAX_KEYS];
char nullv[INDEX_MAX_KEYS];
int i;
if (IsIgnoringSystemIndexes() || (!heapRelation->rd_rel->relhasindex))
2000-02-18 10:30:20 +01:00
return;
1998-09-01 05:29:17 +02:00
heapDescriptor = RelationGetDescr(heapRelation);
for (i = 0; i < nIndices; i++)
{
IndexInfo *indexInfo;
InsertIndexResult indexRes;
indexInfo = BuildIndexInfo(idescs[i]->rd_index);
1999-05-25 18:15:34 +02:00
FormIndexDatum(indexInfo,
heapTuple,
heapDescriptor,
CurrentMemoryContext,
1998-09-03 01:05:37 +02:00
datum,
nullv);
indexRes = index_insert(idescs[i], datum, nullv,
&heapTuple->t_self, heapRelation,
idescs[i]->rd_uniqueindex);
if (indexRes)
pfree(indexRes);
pfree(indexInfo);
}
}