PostgreSQL Source Code  git master
sortsupport.c File Reference
#include "postgres.h"
#include "access/nbtree.h"
#include "catalog/pg_am.h"
#include "fmgr.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/sortsupport.h"
Include dependency graph for sortsupport.c:

Go to the source code of this file.

Data Structures

struct  SortShimExtra
 

Macros

#define SizeForSortShimExtra(nargs)   (offsetof(SortShimExtra, fcinfo) + SizeForFunctionCallInfo(nargs))
 

Functions

static int comparison_shim (Datum x, Datum y, SortSupport ssup)
 
void PrepareSortSupportComparisonShim (Oid cmpFunc, SortSupport ssup)
 
static void FinishSortSupportFunction (Oid opfamily, Oid opcintype, SortSupport ssup)
 
void PrepareSortSupportFromOrderingOp (Oid orderingOp, SortSupport ssup)
 
void PrepareSortSupportFromIndexRel (Relation indexRel, int16 strategy, SortSupport ssup)
 

Macro Definition Documentation

◆ SizeForSortShimExtra

#define SizeForSortShimExtra (   nargs)    (offsetof(SortShimExtra, fcinfo) + SizeForFunctionCallInfo(nargs))

Definition at line 33 of file sortsupport.c.

Referenced by PrepareSortSupportComparisonShim().

Function Documentation

◆ comparison_shim()

static int comparison_shim ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 43 of file sortsupport.c.

References FunctionCallInfoBaseData::args, elog, ERROR, SortShimExtra::fcinfo, SortShimExtra::flinfo, FmgrInfo::fn_oid, FunctionCallInvoke, FunctionCallInfoBaseData::isnull, SortSupportData::ssup_extra, and NullableDatum::value.

Referenced by PrepareSortSupportComparisonShim().

44 {
45  SortShimExtra *extra = (SortShimExtra *) ssup->ssup_extra;
46  Datum result;
47 
48  extra->fcinfo.args[0].value = x;
49  extra->fcinfo.args[1].value = y;
50 
51  /* just for paranoia's sake, we reset isnull each time */
52  extra->fcinfo.isnull = false;
53 
54  result = FunctionCallInvoke(&extra->fcinfo);
55 
56  /* Check for null result, since caller is clearly not expecting one */
57  if (extra->fcinfo.isnull)
58  elog(ERROR, "function %u returned NULL", extra->flinfo.fn_oid);
59 
60  return result;
61 }
FunctionCallInfoBaseData fcinfo
Definition: sortsupport.c:30
#define ERROR
Definition: elog.h:43
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:167
void * ssup_extra
Definition: sortsupport.h:87
Datum value
Definition: postgres.h:378
uintptr_t Datum
Definition: postgres.h:367
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo flinfo
Definition: sortsupport.c:29
#define elog(elevel,...)
Definition: elog.h:226

◆ FinishSortSupportFunction()

static void FinishSortSupportFunction ( Oid  opfamily,
Oid  opcintype,
SortSupport  ssup 
)
static

Definition at line 94 of file sortsupport.c.

References BTORDER_PROC, BTSORTSUPPORT_PROC, SortSupportData::comparator, elog, ERROR, get_opfamily_proc(), OidFunctionCall1, OidIsValid, PointerGetDatum, and PrepareSortSupportComparisonShim().

Referenced by PrepareSortSupportFromIndexRel(), and PrepareSortSupportFromOrderingOp().

95 {
96  Oid sortSupportFunction;
97 
98  /* Look for a sort support function */
99  sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
101  if (OidIsValid(sortSupportFunction))
102  {
103  /*
104  * The sort support function can provide a comparator, but it can also
105  * choose not to so (e.g. based on the selected collation).
106  */
107  OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup));
108  }
109 
110  if (ssup->comparator == NULL)
111  {
112  Oid sortFunction;
113 
114  sortFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
115  BTORDER_PROC);
116 
117  if (!OidIsValid(sortFunction))
118  elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
119  BTORDER_PROC, opcintype, opcintype, opfamily);
120 
121  /* We'll use a shim to call the old-style btree comparator */
122  PrepareSortSupportComparisonShim(sortFunction, ssup);
123  }
124 }
#define BTORDER_PROC
Definition: nbtree.h:392
#define BTSORTSUPPORT_PROC
Definition: nbtree.h:393
void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
Definition: sortsupport.c:68
#define PointerGetDatum(X)
Definition: postgres.h:556
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:655
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
Definition: lsyscache.c:744
#define elog(elevel,...)
Definition: elog.h:226

◆ PrepareSortSupportComparisonShim()

void PrepareSortSupportComparisonShim ( Oid  cmpFunc,
SortSupport  ssup 
)

Definition at line 68 of file sortsupport.c.

References FunctionCallInfoBaseData::args, SortSupportData::comparator, comparison_shim(), SortShimExtra::fcinfo, SortShimExtra::flinfo, fmgr_info_cxt(), InitFunctionCallInfoData, NullableDatum::isnull, MemoryContextAlloc(), SizeForSortShimExtra, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, and SortSupportData::ssup_extra.

Referenced by ApplySortAbbrevFullComparator(), FinishSortSupportFunction(), and MJExamineQuals().

69 {
70  SortShimExtra *extra;
71 
72  extra = (SortShimExtra *) MemoryContextAlloc(ssup->ssup_cxt,
74 
75  /* Lookup the comparison function */
76  fmgr_info_cxt(cmpFunc, &extra->flinfo, ssup->ssup_cxt);
77 
78  /* We can initialize the callinfo just once and re-use it */
79  InitFunctionCallInfoData(extra->fcinfo, &extra->flinfo, 2,
80  ssup->ssup_collation, NULL, NULL);
81  extra->fcinfo.args[0].isnull = false;
82  extra->fcinfo.args[1].isnull = false;
83 
84  ssup->ssup_extra = extra;
86 }
FunctionCallInfoBaseData fcinfo
Definition: sortsupport.c:30
#define SizeForSortShimExtra(nargs)
Definition: sortsupport.c:33
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
MemoryContext ssup_cxt
Definition: sortsupport.h:66
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
void * ssup_extra
Definition: sortsupport.h:87
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
static int comparison_shim(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.c:43
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
FmgrInfo flinfo
Definition: sortsupport.c:29
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771

◆ PrepareSortSupportFromIndexRel()

void PrepareSortSupportFromIndexRel ( Relation  indexRel,
int16  strategy,
SortSupport  ssup 
)

Definition at line 161 of file sortsupport.c.

References Assert, BTGreaterStrategyNumber, BTLessStrategyNumber, SortSupportData::comparator, elog, ERROR, FinishSortSupportFunction(), RelationData::rd_opcintype, RelationData::rd_opfamily, RelationData::rd_rel, SortSupportData::ssup_attno, and SortSupportData::ssup_reverse.

Referenced by _bt_load(), ApplySortAbbrevFullComparator(), tuplesort_begin_cluster(), and tuplesort_begin_index_btree().

163 {
164  Oid opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1];
165  Oid opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1];
166 
167  Assert(ssup->comparator == NULL);
168 
169  if (indexRel->rd_rel->relam != BTREE_AM_OID)
170  elog(ERROR, "unexpected non-btree AM: %u", indexRel->rd_rel->relam);
171  if (strategy != BTGreaterStrategyNumber &&
172  strategy != BTLessStrategyNumber)
173  elog(ERROR, "unexpected sort support strategy: %d", strategy);
174  ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
175 
176  FinishSortSupportFunction(opfamily, opcintype, ssup);
177 }
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
Form_pg_class rd_rel
Definition: rel.h:83
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Oid * rd_opfamily
Definition: rel.h:158
static void FinishSortSupportFunction(Oid opfamily, Oid opcintype, SortSupport ssup)
Definition: sortsupport.c:94
AttrNumber ssup_attno
Definition: sortsupport.h:81
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
Oid * rd_opcintype
Definition: rel.h:159
#define BTLessStrategyNumber
Definition: stratnum.h:29

◆ PrepareSortSupportFromOrderingOp()

void PrepareSortSupportFromOrderingOp ( Oid  orderingOp,
SortSupport  ssup 
)

Definition at line 134 of file sortsupport.c.

References Assert, BTGreaterStrategyNumber, SortSupportData::comparator, elog, ERROR, FinishSortSupportFunction(), get_ordering_op_properties(), and SortSupportData::ssup_reverse.

Referenced by ApplySortAbbrevFullComparator(), compute_scalar_stats(), ExecInitGatherMerge(), ExecInitIndexScan(), ExecInitMergeAppend(), multi_sort_add_dimension(), statext_mcv_serialize(), tuplesort_begin_datum(), and tuplesort_begin_heap().

135 {
136  Oid opfamily;
137  Oid opcintype;
138  int16 strategy;
139 
140  Assert(ssup->comparator == NULL);
141 
142  /* Find the operator in pg_amop */
143  if (!get_ordering_op_properties(orderingOp, &opfamily, &opcintype,
144  &strategy))
145  elog(ERROR, "operator %u is not a valid ordering operator",
146  orderingOp);
147  ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
148 
149  FinishSortSupportFunction(opfamily, opcintype, ssup);
150 }
signed short int16
Definition: c.h:345
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
static void FinishSortSupportFunction(Oid opfamily, Oid opcintype, SortSupport ssup)
Definition: sortsupport.c:94
#define Assert(condition)
Definition: c.h:732
bool get_ordering_op_properties(Oid opno, Oid *opfamily, Oid *opcintype, int16 *strategy)
Definition: lsyscache.c:204
#define elog(elevel,...)
Definition: elog.h:226