LCOV - differential code coverage report
Current view: top level - src/backend/utils/sort - sortsupport.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 87.9 % 58 51 7 51
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 6 6 6
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 87.9 % 58 51 7 51
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 6 6 6

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * sortsupport.c
                                  4                 :  *    Support routines for accelerated sorting.
                                  5                 :  *
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/backend/utils/sort/sortsupport.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : 
                                 16                 : #include "postgres.h"
                                 17                 : 
                                 18                 : #include "access/gist.h"
                                 19                 : #include "access/nbtree.h"
                                 20                 : #include "catalog/pg_am.h"
                                 21                 : #include "fmgr.h"
                                 22                 : #include "utils/lsyscache.h"
                                 23                 : #include "utils/rel.h"
                                 24                 : #include "utils/sortsupport.h"
                                 25                 : 
                                 26                 : 
                                 27                 : /* Info needed to use an old-style comparison function as a sort comparator */
                                 28                 : typedef struct
                                 29                 : {
                                 30                 :     FmgrInfo    flinfo;         /* lookup data for comparison function */
                                 31                 :     FunctionCallInfoBaseData fcinfo;    /* reusable callinfo structure */
                                 32                 : } SortShimExtra;
                                 33                 : 
                                 34                 : #define SizeForSortShimExtra(nargs) (offsetof(SortShimExtra, fcinfo) + SizeForFunctionCallInfo(nargs))
                                 35                 : 
                                 36                 : /*
                                 37                 :  * Shim function for calling an old-style comparator
                                 38                 :  *
                                 39                 :  * This is essentially an inlined version of FunctionCall2Coll(), except
                                 40                 :  * we assume that the FunctionCallInfoBaseData was already mostly set up by
                                 41                 :  * PrepareSortSupportComparisonShim.
                                 42                 :  */
                                 43                 : static int
 4141 tgl                        44 CBC   218941097 : comparison_shim(Datum x, Datum y, SortSupport ssup)
                                 45                 : {
                                 46       218941097 :     SortShimExtra *extra = (SortShimExtra *) ssup->ssup_extra;
                                 47                 :     Datum       result;
                                 48                 : 
 1534 andres                     49       218941097 :     extra->fcinfo.args[0].value = x;
                                 50       218941097 :     extra->fcinfo.args[1].value = y;
                                 51                 : 
                                 52                 :     /* just for paranoia's sake, we reset isnull each time */
 4141 tgl                        53       218941097 :     extra->fcinfo.isnull = false;
                                 54                 : 
                                 55       218941097 :     result = FunctionCallInvoke(&extra->fcinfo);
                                 56                 : 
                                 57                 :     /* Check for null result, since caller is clearly not expecting one */
                                 58       218941097 :     if (extra->fcinfo.isnull)
 4141 tgl                        59 UBC           0 :         elog(ERROR, "function %u returned NULL", extra->flinfo.fn_oid);
                                 60                 : 
 4141 tgl                        61 CBC   218941097 :     return result;
                                 62                 : }
                                 63                 : 
                                 64                 : /*
                                 65                 :  * Set up a shim function to allow use of an old-style btree comparison
                                 66                 :  * function as if it were a sort support comparator.
                                 67                 :  */
                                 68                 : void
                                 69           45317 : PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
                                 70                 : {
                                 71                 :     SortShimExtra *extra;
                                 72                 : 
                                 73           45317 :     extra = (SortShimExtra *) MemoryContextAlloc(ssup->ssup_cxt,
                                 74                 :                                                  SizeForSortShimExtra(2));
                                 75                 : 
                                 76                 :     /* Lookup the comparison function */
                                 77           45317 :     fmgr_info_cxt(cmpFunc, &extra->flinfo, ssup->ssup_cxt);
                                 78                 : 
                                 79                 :     /* We can initialize the callinfo just once and re-use it */
                                 80           45317 :     InitFunctionCallInfoData(extra->fcinfo, &extra->flinfo, 2,
                                 81                 :                              ssup->ssup_collation, NULL, NULL);
 1534 andres                     82           45317 :     extra->fcinfo.args[0].isnull = false;
                                 83           45317 :     extra->fcinfo.args[1].isnull = false;
                                 84                 : 
 4141 tgl                        85           45317 :     ssup->ssup_extra = extra;
                                 86           45317 :     ssup->comparator = comparison_shim;
                                 87           45317 : }
                                 88                 : 
                                 89                 : /*
                                 90                 :  * Look up and call sortsupport function to setup SortSupport comparator;
                                 91                 :  * or if no such function exists or it declines to set up the appropriate
                                 92                 :  * state, prepare a suitable shim.
                                 93                 :  */
                                 94                 : static void
 3075 rhaas                      95          423529 : FinishSortSupportFunction(Oid opfamily, Oid opcintype, SortSupport ssup)
                                 96                 : {
                                 97                 :     Oid         sortSupportFunction;
                                 98                 : 
                                 99                 :     /* Look for a sort support function */
 3168                           100          423529 :     sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
                                101                 :                                             BTSORTSUPPORT_PROC);
                                102          423529 :     if (OidIsValid(sortSupportFunction))
                                103                 :     {
                                104                 :         /*
                                105                 :          * The sort support function can provide a comparator, but it can also
                                106                 :          * choose not to so (e.g. based on the selected collation).
                                107                 :          */
                                108          378411 :         OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup));
                                109                 :     }
                                110                 : 
                                111          423520 :     if (ssup->comparator == NULL)
                                112                 :     {
                                113                 :         Oid         sortFunction;
                                114                 : 
                                115           45118 :         sortFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
                                116                 :                                          BTORDER_PROC);
                                117                 : 
                                118           45118 :         if (!OidIsValid(sortFunction))
 3168 rhaas                     119 UBC           0 :             elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
                                120                 :                  BTORDER_PROC, opcintype, opcintype, opfamily);
                                121                 : 
                                122                 :         /* We'll use a shim to call the old-style btree comparator */
 4141 tgl                       123 CBC       45118 :         PrepareSortSupportComparisonShim(sortFunction, ssup);
                                124                 :     }
                                125          423520 : }
                                126                 : 
                                127                 : /*
                                128                 :  * Fill in SortSupport given an ordering operator (btree "<" or ">" operator).
                                129                 :  *
                                130                 :  * Caller must previously have zeroed the SortSupportData structure and then
                                131                 :  * filled in ssup_cxt, ssup_collation, and ssup_nulls_first.  This will fill
                                132                 :  * in ssup_reverse as well as the comparator function pointer.
                                133                 :  */
                                134                 : void
 3075 rhaas                     135          216309 : PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
                                136                 : {
                                137                 :     Oid         opfamily;
                                138                 :     Oid         opcintype;
                                139                 :     int16       strategy;
                                140                 : 
                                141          216309 :     Assert(ssup->comparator == NULL);
                                142                 : 
                                143                 :     /* Find the operator in pg_amop */
                                144          216309 :     if (!get_ordering_op_properties(orderingOp, &opfamily, &opcintype,
                                145                 :                                     &strategy))
 3075 rhaas                     146 UBC           0 :         elog(ERROR, "operator %u is not a valid ordering operator",
                                147                 :              orderingOp);
 3075 rhaas                     148 CBC      216309 :     ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
                                149                 : 
                                150          216309 :     FinishSortSupportFunction(opfamily, opcintype, ssup);
                                151          216300 : }
                                152                 : 
                                153                 : /*
                                154                 :  * Fill in SortSupport given an index relation, attribute, and strategy.
                                155                 :  *
                                156                 :  * Caller must previously have zeroed the SortSupportData structure and then
                                157                 :  * filled in ssup_cxt, ssup_attno, ssup_collation, and ssup_nulls_first.  This
                                158                 :  * will fill in ssup_reverse (based on the supplied strategy), as well as the
                                159                 :  * comparator function pointer.
                                160                 :  */
                                161                 : void
                                162          207220 : PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy,
                                163                 :                                SortSupport ssup)
                                164                 : {
                                165          207220 :     Oid         opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1];
                                166          207220 :     Oid         opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1];
                                167                 : 
                                168          207220 :     Assert(ssup->comparator == NULL);
                                169                 : 
                                170          207220 :     if (indexRel->rd_rel->relam != BTREE_AM_OID)
 3075 rhaas                     171 UBC           0 :         elog(ERROR, "unexpected non-btree AM: %u", indexRel->rd_rel->relam);
 3075 rhaas                     172 CBC      207220 :     if (strategy != BTGreaterStrategyNumber &&
                                173                 :         strategy != BTLessStrategyNumber)
 3075 rhaas                     174 UBC           0 :         elog(ERROR, "unexpected sort support strategy: %d", strategy);
 3075 rhaas                     175 CBC      207220 :     ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
                                176                 : 
                                177          207220 :     FinishSortSupportFunction(opfamily, opcintype, ssup);
                                178          207220 : }
                                179                 : 
                                180                 : /*
                                181                 :  * Fill in SortSupport given a GiST index relation
                                182                 :  *
                                183                 :  * Caller must previously have zeroed the SortSupportData structure and then
                                184                 :  * filled in ssup_cxt, ssup_attno, ssup_collation, and ssup_nulls_first.  This
                                185                 :  * will fill in ssup_reverse (always false for GiST index build), as well as
                                186                 :  * the comparator function pointer.
                                187                 :  */
                                188                 : void
  934 heikki.linnakangas        189              69 : PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup)
                                190                 : {
                                191              69 :     Oid         opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1];
                                192              69 :     Oid         opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1];
                                193                 :     Oid         sortSupportFunction;
                                194                 : 
                                195              69 :     Assert(ssup->comparator == NULL);
                                196                 : 
                                197              69 :     if (indexRel->rd_rel->relam != GIST_AM_OID)
  934 heikki.linnakangas        198 UBC           0 :         elog(ERROR, "unexpected non-gist AM: %u", indexRel->rd_rel->relam);
  934 heikki.linnakangas        199 CBC          69 :     ssup->ssup_reverse = false;
                                200                 : 
                                201                 :     /*
                                202                 :      * Look up the sort support function. This is simpler than for B-tree
                                203                 :      * indexes because we don't support the old-style btree comparators.
                                204                 :      */
                                205              69 :     sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
                                206                 :                                             GIST_SORTSUPPORT_PROC);
                                207              69 :     if (!OidIsValid(sortSupportFunction))
  934 heikki.linnakangas        208 UBC           0 :         elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
                                209                 :              GIST_SORTSUPPORT_PROC, opcintype, opcintype, opfamily);
  934 heikki.linnakangas        210 CBC          69 :     OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup));
                                211              69 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a