summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-07-06 14:53:16 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-07-06 14:53:42 -0400
commitcb1cc305bc349338f75a549c36041b4c91cf779f (patch)
treef0bcbdd58dd7d7d77ed856e970f4cb9a78cfc922 /src/backend/utils
parentf8bd267d35503109255c99eae96c86ba8ba1b56f (diff)
downloadpostgresql-cb1cc305bc349338f75a549c36041b4c91cf779f.tar.gz
Remove assumptions that not-equals operators cannot be in any opclass.
get_op_btree_interpretation assumed this in order to save some duplication of code, but it's not true in general anymore because we added <> support to btree_gist. (We still assume it for btree opclasses, though.) Also, essentially the same logic was baked into predtest.c. Get rid of that duplication by generalizing get_op_btree_interpretation so that it can be used by predtest.c. Per bug report from Denis de Bernardy and investigation by Jeff Davis, though I didn't use Jeff's patch exactly as-is. Back-patch to 9.1; we do not support this usage before that.
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/cache/lsyscache.c97
1 files changed, 59 insertions, 38 deletions
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 28d18b0d32..a59bb1bc1a 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -622,52 +622,30 @@ get_op_hash_functions(Oid opno,
/*
* get_op_btree_interpretation
* Given an operator's OID, find out which btree opfamilies it belongs to,
- * and what strategy number it has within each one. The results are
- * returned as an OID list and a parallel integer list.
+ * and what properties it has within each one. The results are returned
+ * as a palloc'd list of OpBtreeInterpretation structs.
*
* In addition to the normal btree operators, we consider a <> operator to be
* a "member" of an opfamily if its negator is an equality operator of the
* opfamily. ROWCOMPARE_NE is returned as the strategy number for this case.
*/
-void
-get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
+List *
+get_op_btree_interpretation(Oid opno)
{
+ List *result = NIL;
+ OpBtreeInterpretation *thisresult;
CatCList *catlist;
- bool op_negated;
int i;
- *opfamilies = NIL;
- *opstrats = NIL;
-
/*
* Find all the pg_amop entries containing the operator.
*/
catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(opno));
- /*
- * If we can't find any opfamily containing the op, perhaps it is a <>
- * operator. See if it has a negator that is in an opfamily.
- */
- op_negated = false;
- if (catlist->n_members == 0)
- {
- Oid op_negator = get_negator(opno);
-
- if (OidIsValid(op_negator))
- {
- op_negated = true;
- ReleaseSysCacheList(catlist);
- catlist = SearchSysCacheList1(AMOPOPID,
- ObjectIdGetDatum(op_negator));
- }
- }
-
- /* Now search the opfamilies */
for (i = 0; i < catlist->n_members; i++)
{
HeapTuple op_tuple = &catlist->members[i]->tuple;
Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
- Oid opfamily_id;
StrategyNumber op_strategy;
/* must be btree */
@@ -675,23 +653,66 @@ get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
continue;
/* Get the operator's btree strategy number */
- opfamily_id = op_form->amopfamily;
op_strategy = (StrategyNumber) op_form->amopstrategy;
Assert(op_strategy >= 1 && op_strategy <= 5);
- if (op_negated)
+ thisresult = (OpBtreeInterpretation *)
+ palloc(sizeof(OpBtreeInterpretation));
+ thisresult->opfamily_id = op_form->amopfamily;
+ thisresult->strategy = op_strategy;
+ thisresult->oplefttype = op_form->amoplefttype;
+ thisresult->oprighttype = op_form->amoprighttype;
+ result = lappend(result, thisresult);
+ }
+
+ ReleaseSysCacheList(catlist);
+
+ /*
+ * If we didn't find any btree opfamily containing the operator, perhaps
+ * it is a <> operator. See if it has a negator that is in an opfamily.
+ */
+ if (result == NIL)
+ {
+ Oid op_negator = get_negator(opno);
+
+ if (OidIsValid(op_negator))
{
- /* Only consider negators that are = */
- if (op_strategy != BTEqualStrategyNumber)
- continue;
- op_strategy = ROWCOMPARE_NE;
- }
+ catlist = SearchSysCacheList1(AMOPOPID,
+ ObjectIdGetDatum(op_negator));
- *opfamilies = lappend_oid(*opfamilies, opfamily_id);
- *opstrats = lappend_int(*opstrats, op_strategy);
+ for (i = 0; i < catlist->n_members; i++)
+ {
+ HeapTuple op_tuple = &catlist->members[i]->tuple;
+ Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
+ StrategyNumber op_strategy;
+
+ /* must be btree */
+ if (op_form->amopmethod != BTREE_AM_OID)
+ continue;
+
+ /* Get the operator's btree strategy number */
+ op_strategy = (StrategyNumber) op_form->amopstrategy;
+ Assert(op_strategy >= 1 && op_strategy <= 5);
+
+ /* Only consider negators that are = */
+ if (op_strategy != BTEqualStrategyNumber)
+ continue;
+
+ /* OK, report it with "strategy" ROWCOMPARE_NE */
+ thisresult = (OpBtreeInterpretation *)
+ palloc(sizeof(OpBtreeInterpretation));
+ thisresult->opfamily_id = op_form->amopfamily;
+ thisresult->strategy = ROWCOMPARE_NE;
+ thisresult->oplefttype = op_form->amoplefttype;
+ thisresult->oprighttype = op_form->amoprighttype;
+ result = lappend(result, thisresult);
+ }
+
+ ReleaseSysCacheList(catlist);
+ }
}
- ReleaseSysCacheList(catlist);
+ return result;
}
/*