]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/cache/lsyscache.c
Create a "sort support" interface API for faster sorting.
[postgresql] / src / backend / utils / cache / lsyscache.c
index ceca0e3ede0f1b5584ae290b4cb08cd369d8bd10..7a4306e93f5545764cbd02e6aa042120b385790c 100644 (file)
@@ -244,19 +244,22 @@ get_ordering_op_properties(Oid opno,
 }
 
 /*
- * get_compare_function_for_ordering_op
- *             Get the OID of the datatype-specific btree comparison function
+ * 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).
  *
- * *cmpfunc receives the comparison function OID.
+ * *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 the comparison result must be negated before use).
+ * (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_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
+get_sort_function_for_ordering_op(Oid opno, Oid *sortfunc,
+                                                                 bool *issupport, bool *reverse)
 {
        Oid                     opfamily;
        Oid                     opcintype;
@@ -267,21 +270,31 @@ get_compare_function_for_ordering_op(Oid opno, Oid *cmpfunc, bool *reverse)
                                                                   &opfamily, &opcintype, &strategy))
        {
                /* Found a suitable opfamily, get matching support function */
-               *cmpfunc = get_opfamily_proc(opfamily,
-                                                                        opcintype,
-                                                                        opcintype,
-                                                                        BTORDER_PROC);
-
-               if (!OidIsValid(*cmpfunc))              /* should not happen */
-                       elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
-                                BTORDER_PROC, opcintype, opcintype, opfamily);
+               *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 */
-       *cmpfunc = InvalidOid;
-
+       *sortfunc = InvalidOid;
+       *issupport = false;
        *reverse = false;
        return false;
 }
@@ -1890,10 +1903,9 @@ getTypeIOParam(HeapTuple typeTuple)
 
        /*
         * Array types get their typelem as parameter; everybody else gets their
-        * own type OID as parameter.  (As of 8.2, domains must get their own OID
-        * even if their base type is an array.)
+        * own type OID as parameter.
         */
-       if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem))
+       if (OidIsValid(typeStruct->typelem))
                return typeStruct->typelem;
        else
                return HeapTupleGetOid(typeTuple);