diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-11-12 21:15:59 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-11-12 21:15:59 +0000 |
| commit | fa5c8a055a02e44f446e4593e397c33a572c4d67 (patch) | |
| tree | 9c0a7ded5a88c082c28dbe2b431660813abd72b8 /src/backend/utils/cache | |
| parent | 49f98fa833407b4e4252e42522e640ec8a0d08b2 (diff) | |
| download | postgresql-fa5c8a055a02e44f446e4593e397c33a572c4d67.tar.gz | |
Cross-data-type comparisons are now indexable by btrees, pursuant to my
pghackers proposal of 8-Nov. All the existing cross-type comparison
operators (int2/int4/int8 and float4/float8) have appropriate support.
The original proposal of storing the right-hand-side datatype as part of
the primary key for pg_amop and pg_amproc got modified a bit in the event;
it is easier to store zero as the 'default' case and only store a nonzero
when the operator is actually cross-type. Along the way, remove the
long-since-defunct bigbox_ops operator class.
Diffstat (limited to 'src/backend/utils/cache')
| -rw-r--r-- | src/backend/utils/cache/catcache.c | 6 | ||||
| -rw-r--r-- | src/backend/utils/cache/lsyscache.c | 25 | ||||
| -rw-r--r-- | src/backend/utils/cache/relcache.c | 172 | ||||
| -rw-r--r-- | src/backend/utils/cache/syscache.c | 10 | ||||
| -rw-r--r-- | src/backend/utils/cache/typcache.c | 15 |
5 files changed, 113 insertions, 115 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 640629c3a0..36125c2374 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.110 2003/11/12 21:15:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -967,9 +967,9 @@ CatalogCacheInitializeCache(CatCache *cache) /* Initialize sk_attno suitably for HeapKeyTest() and heap scans */ cache->cc_skey[i].sk_attno = cache->cc_key[i]; - /* Fill in sk_strategy and sk_argtype correctly as well */ + /* Fill in sk_strategy as well --- always standard equality */ cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber; - cache->cc_skey[i].sk_argtype = keytype; + cache->cc_skey[i].sk_subtype = InvalidOid; CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p", cache->cc_relname, diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index bed4fcdbce..20c10802bc 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.110 2003/11/12 21:15:55 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -55,7 +55,7 @@ op_in_opclass(Oid opno, Oid opclass) /* * get_op_opclass_properties * - * Get the operator's strategy number and recheck (lossy) flag + * Get the operator's strategy number, subtype, and recheck (lossy) flag * within the specified opclass. * * Caller should already have verified that opno is a member of opclass, @@ -63,7 +63,7 @@ op_in_opclass(Oid opno, Oid opclass) */ void get_op_opclass_properties(Oid opno, Oid opclass, - int *strategy, bool *recheck) + int *strategy, Oid *subtype, bool *recheck) { HeapTuple tp; Form_pg_amop amop_tup; @@ -77,6 +77,7 @@ get_op_opclass_properties(Oid opno, Oid opclass, opno, opclass); amop_tup = (Form_pg_amop) GETSTRUCT(tp); *strategy = amop_tup->amopstrategy; + *subtype = amop_tup->amopsubtype; *recheck = amop_tup->amopreqcheck; ReleaseSysCache(tp); } @@ -84,12 +85,12 @@ get_op_opclass_properties(Oid opno, Oid opclass, /* * get_opclass_member * Get the OID of the operator that implements the specified strategy - * for the specified opclass. + * with the specified subtype for the specified opclass. * * Returns InvalidOid if there is no pg_amop entry for the given keys. */ Oid -get_opclass_member(Oid opclass, int16 strategy) +get_opclass_member(Oid opclass, Oid subtype, int16 strategy) { HeapTuple tp; Form_pg_amop amop_tup; @@ -97,8 +98,9 @@ get_opclass_member(Oid opclass, int16 strategy) tp = SearchSysCache(AMOPSTRATEGY, ObjectIdGetDatum(opclass), + ObjectIdGetDatum(subtype), Int16GetDatum(strategy), - 0, 0); + 0); if (!HeapTupleIsValid(tp)) return InvalidOid; amop_tup = (Form_pg_amop) GETSTRUCT(tp); @@ -149,8 +151,8 @@ get_op_hash_function(Oid opno) if (OidIsValid(opclass)) { - /* Found a suitable opclass, get its hash support function */ - return get_opclass_proc(opclass, HASHPROC); + /* Found a suitable opclass, get its default hash support function */ + return get_opclass_proc(opclass, InvalidOid, HASHPROC); } /* Didn't find a match... */ @@ -163,12 +165,12 @@ get_op_hash_function(Oid opno) /* * get_opclass_proc * Get the OID of the specified support function - * for the specified opclass. + * for the specified opclass and subtype. * * Returns InvalidOid if there is no pg_amproc entry for the given keys. */ Oid -get_opclass_proc(Oid opclass, int16 procnum) +get_opclass_proc(Oid opclass, Oid subtype, int16 procnum) { HeapTuple tp; Form_pg_amproc amproc_tup; @@ -176,8 +178,9 @@ get_opclass_proc(Oid opclass, int16 procnum) tp = SearchSysCache(AMPROCNUM, ObjectIdGetDatum(opclass), + ObjectIdGetDatum(subtype), Int16GetDatum(procnum), - 0, 0); + 0); if (!HeapTupleIsValid(tp)) return InvalidOid; amproc_tup = (Form_pg_amproc) GETSTRUCT(tp); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 88c8cbb141..ac5e53a91a 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.191 2003/11/09 21:30:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.192 2003/11/12 21:15:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -262,7 +262,7 @@ do { \ /* * Special cache for opclass-related information * - * Note: only non-cross-type operators and support procs get cached + * Note: only default-subtype operators and support procs get cached */ typedef struct opclasscacheent { @@ -336,26 +336,23 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK) switch (buildinfo.infotype) { case INFO_RELID: - ScanKeyEntryInitialize(&key[0], 0, - ObjectIdAttributeNumber, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(buildinfo.i.info_id), - OIDOID); + ScanKeyInit(&key[0], + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(buildinfo.i.info_id)); nkeys = 1; indexRelname = ClassOidIndex; break; case INFO_RELNAME: - ScanKeyEntryInitialize(&key[0], 0, - Anum_pg_class_relname, - BTEqualStrategyNumber, F_NAMEEQ, - NameGetDatum(buildinfo.i.info_name), - NAMEOID); - ScanKeyEntryInitialize(&key[1], 0, - Anum_pg_class_relnamespace, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(PG_CATALOG_NAMESPACE), - OIDOID); + ScanKeyInit(&key[0], + Anum_pg_class_relname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(buildinfo.i.info_name)); + ScanKeyInit(&key[1], + Anum_pg_class_relnamespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(PG_CATALOG_NAMESPACE)); nkeys = 2; indexRelname = ClassNameNspIndex; break; @@ -483,15 +480,14 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, * (Eliminating system attribute rows at the index level is lots * faster than fetching them.) */ - ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_attribute_attrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation)), - OIDOID); - ScanKeyEntryInitialize(&skey[1], 0, - Anum_pg_attribute_attnum, - BTGreaterStrategyNumber, F_INT2GT, - Int16GetDatum(0), INT2OID); + ScanKeyInit(&skey[0], + Anum_pg_attribute_attrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyInit(&skey[1], + Anum_pg_attribute_attnum, + BTGreaterStrategyNumber, F_INT2GT, + Int16GetDatum(0)); /* * Open pg_attribute and begin a scan. Force heap scan if we haven't @@ -673,11 +669,10 @@ RelationBuildRuleLock(Relation relation) /* * form a scan key */ - ScanKeyEntryInitialize(&key, 0, - Anum_pg_rewrite_ev_class, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation)), - OIDOID); + ScanKeyInit(&key, + Anum_pg_rewrite_ev_class, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation))); /* * open pg_rewrite and begin a scan @@ -1058,7 +1053,7 @@ RelationInitIndexAccessInfo(Relation relation) /* * IndexSupportInitialize - * Initializes an index's cached lists of operators and support procs, + * Initializes an index's cached opclass information, * given the index's pg_index tuple. * * Data is returned into *indexOperator and *indexSupport, which are arrays @@ -1131,11 +1126,9 @@ LookupOpclassInfo(Oid operatorClassOid, { OpClassCacheEnt *opcentry; bool found; - Relation pg_amop_desc; - Relation pg_amproc_desc; - SysScanDesc pg_amop_scan; - SysScanDesc pg_amproc_scan; - ScanKeyData key; + Relation rel; + SysScanDesc scan; + ScanKeyData skey[2]; HeapTuple htup; bool indexOK; @@ -1191,7 +1184,7 @@ LookupOpclassInfo(Oid operatorClassOid, opcentry->supportProcs = NULL; /* - * To avoid infinite recursion during startup, force a heap scan if + * To avoid infinite recursion during startup, force heap scans if * we're looking up info for the opclasses used by the indexes we * would like to reference here. */ @@ -1200,24 +1193,25 @@ LookupOpclassInfo(Oid operatorClassOid, operatorClassOid != INT2_BTREE_OPS_OID); /* - * Scan pg_amop to obtain operators for the opclass + * Scan pg_amop to obtain operators for the opclass. We only fetch + * the default ones (those with subtype zero). */ if (numStrats > 0) { - ScanKeyEntryInitialize(&key, 0, - Anum_pg_amop_amopclaid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(operatorClassOid), - OIDOID); - pg_amop_desc = heap_openr(AccessMethodOperatorRelationName, - AccessShareLock); - pg_amop_scan = systable_beginscan(pg_amop_desc, - AccessMethodStrategyIndex, - indexOK, - SnapshotNow, - 1, &key); - - while (HeapTupleIsValid(htup = systable_getnext(pg_amop_scan))) + ScanKeyInit(&skey[0], + Anum_pg_amop_amopclaid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(operatorClassOid)); + ScanKeyInit(&skey[1], + Anum_pg_amop_amopsubtype, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + rel = heap_openr(AccessMethodOperatorRelationName, + AccessShareLock); + scan = systable_beginscan(rel, AccessMethodStrategyIndex, indexOK, + SnapshotNow, 2, skey); + + while (HeapTupleIsValid(htup = systable_getnext(scan))) { Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup); @@ -1229,29 +1223,30 @@ LookupOpclassInfo(Oid operatorClassOid, amopform->amopopr; } - systable_endscan(pg_amop_scan); - heap_close(pg_amop_desc, AccessShareLock); + systable_endscan(scan); + heap_close(rel, AccessShareLock); } /* - * Scan pg_amproc to obtain support procs for the opclass + * Scan pg_amproc to obtain support procs for the opclass. We only fetch + * the default ones (those with subtype zero). */ if (numSupport > 0) { - ScanKeyEntryInitialize(&key, 0, - Anum_pg_amproc_amopclaid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(operatorClassOid), - OIDOID); - pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName, - AccessShareLock); - pg_amproc_scan = systable_beginscan(pg_amproc_desc, - AccessMethodProcedureIndex, - indexOK, - SnapshotNow, - 1, &key); - - while (HeapTupleIsValid(htup = systable_getnext(pg_amproc_scan))) + ScanKeyInit(&skey[0], + Anum_pg_amproc_amopclaid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(operatorClassOid)); + ScanKeyInit(&skey[1], + Anum_pg_amproc_amprocsubtype, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + rel = heap_openr(AccessMethodProcedureRelationName, + AccessShareLock); + scan = systable_beginscan(rel, AccessMethodProcedureIndex, indexOK, + SnapshotNow, 2, skey); + + while (HeapTupleIsValid(htup = systable_getnext(scan))) { Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup); @@ -1264,8 +1259,8 @@ LookupOpclassInfo(Oid operatorClassOid, amprocform->amproc; } - systable_endscan(pg_amproc_scan); - heap_close(pg_amproc_desc, AccessShareLock); + systable_endscan(scan); + heap_close(rel, AccessShareLock); } opcentry->valid = true; @@ -2483,16 +2478,14 @@ AttrDefaultFetch(Relation relation) int found; int i; - ScanKeyEntryInitialize(&skey, 0, - Anum_pg_attrdef_adrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation)), - OIDOID); + ScanKeyInit(&skey, + Anum_pg_attrdef_adrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation))); adrel = heap_openr(AttrDefaultRelationName, AccessShareLock); adscan = systable_beginscan(adrel, AttrDefaultIndex, true, - SnapshotNow, - 1, &skey); + SnapshotNow, 1, &skey); found = 0; while (HeapTupleIsValid(htup = systable_getnext(adscan))) @@ -2550,11 +2543,10 @@ CheckConstraintFetch(Relation relation) bool isnull; int found = 0; - ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_constraint_conrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation)), - OIDOID); + ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation))); conrel = heap_openr(ConstraintRelationName, AccessShareLock); conscan = systable_beginscan(conrel, ConstraintRelidIndex, true, @@ -2642,16 +2634,14 @@ RelationGetIndexList(Relation relation) result = NIL; /* Prepare to scan pg_index for entries having indrelid = this rel. */ - ScanKeyEntryInitialize(&skey, 0, - Anum_pg_index_indrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation)), - OIDOID); + ScanKeyInit(&skey, + Anum_pg_index_indrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation))); indrel = heap_openr(IndexRelationName, AccessShareLock); indscan = systable_beginscan(indrel, IndexIndrelidIndex, true, - SnapshotNow, - 1, &skey); + SnapshotNow, 1, &skey); while (HeapTupleIsValid(htup = systable_getnext(indscan))) { diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 9b250eef62..eb2f6eb1af 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.91 2003/09/24 18:54:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.92 2003/11/12 21:15:56 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -136,21 +136,21 @@ static const struct cachedesc cacheinfo[] = { {AccessMethodOperatorRelationName, /* AMOPSTRATEGY */ AccessMethodStrategyIndex, 0, - 2, + 3, { Anum_pg_amop_amopclaid, + Anum_pg_amop_amopsubtype, Anum_pg_amop_amopstrategy, - 0, 0 }}, {AccessMethodProcedureRelationName, /* AMPROCNUM */ AccessMethodProcedureIndex, 0, - 2, + 3, { Anum_pg_amproc_amopclaid, + Anum_pg_amproc_amprocsubtype, Anum_pg_amproc_amprocnum, - 0, 0 }}, {AttributeRelationName, /* ATTNAME */ diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 9b7620b0f0..12d295c5a5 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -33,7 +33,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.2 2003/11/09 21:30:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.3 2003/11/12 21:15:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -158,22 +158,26 @@ lookup_type_cache(Oid type_id, int flags) { if (typentry->btree_opc != InvalidOid) typentry->eq_opr = get_opclass_member(typentry->btree_opc, + InvalidOid, BTEqualStrategyNumber); if (typentry->eq_opr == InvalidOid && typentry->hash_opc != InvalidOid) typentry->eq_opr = get_opclass_member(typentry->hash_opc, + InvalidOid, HTEqualStrategyNumber); } if ((flags & TYPECACHE_LT_OPR) && typentry->lt_opr == InvalidOid) { if (typentry->btree_opc != InvalidOid) typentry->lt_opr = get_opclass_member(typentry->btree_opc, + InvalidOid, BTLessStrategyNumber); } if ((flags & TYPECACHE_GT_OPR) && typentry->gt_opr == InvalidOid) { if (typentry->btree_opc != InvalidOid) typentry->gt_opr = get_opclass_member(typentry->btree_opc, + InvalidOid, BTGreaterStrategyNumber); } if ((flags & (TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO)) && @@ -181,6 +185,7 @@ lookup_type_cache(Oid type_id, int flags) { if (typentry->btree_opc != InvalidOid) typentry->cmp_proc = get_opclass_proc(typentry->btree_opc, + InvalidOid, BTORDER_PROC); } @@ -248,10 +253,10 @@ lookup_default_opclass(Oid type_id, Oid am_id) */ rel = heap_openr(OperatorClassRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_opclass_opcamid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(am_id), OIDOID); + ScanKeyInit(&skey[0], + Anum_pg_opclass_opcamid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(am_id)); scan = systable_beginscan(rel, OpclassAmNameNspIndex, true, SnapshotNow, 1, skey); |
