]> granicus.if.org Git - postgresql/commitdiff
Don't require sort support functions to provide a comparator.
authorRobert Haas <rhaas@postgresql.org>
Wed, 6 Aug 2014 20:06:06 +0000 (16:06 -0400)
committerRobert Haas <rhaas@postgresql.org>
Wed, 6 Aug 2014 20:06:06 +0000 (16:06 -0400)
This could be useful for datatypes like text, where we might want
to optimize for some collations but not others.  However, this patch
doesn't introduce any new sortsupport functions that work this way;
it merely revises the code so that future patches may do so.

Patch by me.  Review by Peter Geoghegan.

src/backend/executor/nodeMergejoin.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/sort/sortsupport.c
src/include/utils/lsyscache.h

index bc036a30b0d24d1d750f5184e43453c333740277..fdf2f4c1a852c07b19ffe044cdb257e53ad68c11 100644 (file)
@@ -230,19 +230,19 @@ MJExamineQuals(List *mergeclauses,
                                 qual->opno);
 
                /* And get the matching support or comparison function */
+               Assert(clause->ssup.comparator == NULL);
                sortfunc = get_opfamily_proc(opfamily,
                                                                         op_lefttype,
                                                                         op_righttype,
                                                                         BTSORTSUPPORT_PROC);
                if (OidIsValid(sortfunc))
                {
-                       /* The sort support function should provide a comparator */
+                       /* The sort support function can provide a comparator */
                        OidFunctionCall1(sortfunc, PointerGetDatum(&clause->ssup));
-                       Assert(clause->ssup.comparator != NULL);
                }
-               else
+               if (clause->ssup.comparator == NULL)
                {
-                       /* opfamily doesn't provide sort support, get comparison func */
+                       /* support not available, get comparison func */
                        sortfunc = get_opfamily_proc(opfamily,
                                                                                 op_lefttype,
                                                                                 op_righttype,
index 4b5ef99531bbaf5b7d56faea8c58747dc0956144..552e498cf57b636e0e545c6cd4490a71470f7054 100644 (file)
@@ -245,62 +245,6 @@ get_ordering_op_properties(Oid opno,
        return result;
 }
 
-/*
- * get_sort_function_for_ordering_op
- *             Get the OID of the datatype-specific btree sort support function,
- *             or if there is none, the btree comparison function,
- *             associated with an ordering operator (a "<" or ">" operator).
- *
- * *sortfunc receives the support or comparison function OID.
- * *issupport is set TRUE if it's a support func, FALSE if a comparison func.
- * *reverse is set FALSE if the operator is "<", TRUE if it's ">"
- * (indicating that comparison results must be negated before use).
- *
- * Returns TRUE if successful, FALSE if no btree function can be found.
- * (This indicates that the operator is not a valid ordering operator.)
- */
-bool
-get_sort_function_for_ordering_op(Oid opno, Oid *sortfunc,
-                                                                 bool *issupport, bool *reverse)
-{
-       Oid                     opfamily;
-       Oid                     opcintype;
-       int16           strategy;
-
-       /* Find the operator in pg_amop */
-       if (get_ordering_op_properties(opno,
-                                                                  &opfamily, &opcintype, &strategy))
-       {
-               /* Found a suitable opfamily, get matching support function */
-               *sortfunc = get_opfamily_proc(opfamily,
-                                                                         opcintype,
-                                                                         opcintype,
-                                                                         BTSORTSUPPORT_PROC);
-               if (OidIsValid(*sortfunc))
-                       *issupport = true;
-               else
-               {
-                       /* opfamily doesn't provide sort support, get comparison func */
-                       *sortfunc = get_opfamily_proc(opfamily,
-                                                                                 opcintype,
-                                                                                 opcintype,
-                                                                                 BTORDER_PROC);
-                       if (!OidIsValid(*sortfunc)) /* should not happen */
-                               elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
-                                        BTORDER_PROC, opcintype, opcintype, opfamily);
-                       *issupport = false;
-               }
-               *reverse = (strategy == BTGreaterStrategyNumber);
-               return true;
-       }
-
-       /* ensure outputs are set on failure */
-       *sortfunc = InvalidOid;
-       *issupport = false;
-       *reverse = false;
-       return false;
-}
-
 /*
  * get_equality_op_for_ordering_op
  *             Get the OID of the datatype-specific btree equality operator
index 347f448e0f3e9f6a915ef79b679e805c0208c531..2240fd01001ecdc1f390a0c73d87879d207980ba 100644 (file)
@@ -18,6 +18,7 @@
 /* See sortsupport.h */
 #define SORTSUPPORT_INCLUDE_DEFINITIONS
 
+#include "access/nbtree.h"
 #include "fmgr.h"
 #include "utils/lsyscache.h"
 #include "utils/sortsupport.h"
@@ -94,24 +95,43 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
 void
 PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
 {
-       Oid                     sortFunction;
-       bool            issupport;
+       Oid                     sortSupportFunction;
+       Oid                     opfamily;
+       Oid                     opcintype;
+       int16           strategy;
 
-       if (!get_sort_function_for_ordering_op(orderingOp,
-                                                                                  &sortFunction,
-                                                                                  &issupport,
-                                                                                  &ssup->ssup_reverse))
+       Assert(ssup->comparator == NULL);
+
+       /* Find the operator in pg_amop */
+       if (!get_ordering_op_properties(orderingOp, &opfamily, &opcintype,
+                                                                       &strategy))
                elog(ERROR, "operator %u is not a valid ordering operator",
                         orderingOp);
+       ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
 
-       if (issupport)
+       /* Look for a sort support function */
+       sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
+                                                                                       BTSORTSUPPORT_PROC);
+       if (OidIsValid(sortSupportFunction))
        {
-               /* The sort support function should provide a comparator */
-               OidFunctionCall1(sortFunction, PointerGetDatum(ssup));
-               Assert(ssup->comparator != NULL);
+               /*
+                * The sort support function can provide a comparator, but it can
+                * also choose not to so (e.g. based on the selected collation).
+                */
+               OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup));
        }
-       else
+
+       if (ssup->comparator == NULL)
        {
+               Oid                     sortFunction;
+
+               sortFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
+                                                                                BTORDER_PROC);
+
+               if (!OidIsValid(sortFunction))
+                       elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
+                                BTORDER_PROC, opcintype, opcintype, opfamily);
+
                /* We'll use a shim to call the old-style btree comparator */
                PrepareSortSupportComparisonShim(sortFunction, ssup);
        }
index f46460a5757eeb614bc0003d87de36a761bef052..07d24d4cb8a0284e12cf59dd0a739f3397757c1d 100644 (file)
@@ -50,8 +50,6 @@ extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
                                        int16 strategy);
 extern bool get_ordering_op_properties(Oid opno,
                                                   Oid *opfamily, Oid *opcintype, int16 *strategy);
-extern bool get_sort_function_for_ordering_op(Oid opno, Oid *sortfunc,
-                                                                 bool *issupport, bool *reverse);
 extern Oid     get_equality_op_for_ordering_op(Oid opno, bool *reverse);
 extern Oid     get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type);
 extern List *get_mergejoin_opfamilies(Oid opno);