PostgreSQL Source Code  git master
sortsupport.c File Reference
#include "postgres.h"
#include "access/gist.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)
 
void PrepareSortSupportFromGistIndexRel (Relation indexRel, SortSupport ssup)
 

Macro Definition Documentation

◆ SizeForSortShimExtra

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

Definition at line 34 of file sortsupport.c.

Function Documentation

◆ comparison_shim()

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

Definition at line 44 of file sortsupport.c.

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

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

Referenced by PrepareSortSupportComparisonShim().

◆ FinishSortSupportFunction()

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

Definition at line 95 of file sortsupport.c.

96 {
97  Oid sortSupportFunction;
98 
99  /* Look for a sort support function */
100  sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
102  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  OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup));
109  }
110 
111  if (ssup->comparator == NULL)
112  {
113  Oid sortFunction;
114 
115  sortFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
116  BTORDER_PROC);
117 
118  if (!OidIsValid(sortFunction))
119  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 */
123  PrepareSortSupportComparisonShim(sortFunction, ssup);
124  }
125 }
#define OidIsValid(objectId)
Definition: c.h:711
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:680
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
Definition: lsyscache.c:795
#define BTORDER_PROC
Definition: nbtree.h:701
#define BTSORTSUPPORT_PROC
Definition: nbtree.h:702
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:670
unsigned int Oid
Definition: postgres_ext.h:31
void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
Definition: sortsupport.c:69
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106

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

Referenced by PrepareSortSupportFromIndexRel(), and PrepareSortSupportFromOrderingOp().

◆ PrepareSortSupportComparisonShim()

void PrepareSortSupportComparisonShim ( Oid  cmpFunc,
SortSupport  ssup 
)

Definition at line 69 of file sortsupport.c.

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

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 FinishSortSupportFunction(), and MJExamineQuals().

◆ PrepareSortSupportFromGistIndexRel()

void PrepareSortSupportFromGistIndexRel ( Relation  indexRel,
SortSupport  ssup 
)

Definition at line 189 of file sortsupport.c.

190 {
191  Oid opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1];
192  Oid opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1];
193  Oid sortSupportFunction;
194 
195  Assert(ssup->comparator == NULL);
196 
197  if (indexRel->rd_rel->relam != GIST_AM_OID)
198  elog(ERROR, "unexpected non-gist AM: %u", indexRel->rd_rel->relam);
199  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  sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype,
207  if (!OidIsValid(sortSupportFunction))
208  elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
209  GIST_SORTSUPPORT_PROC, opcintype, opcintype, opfamily);
210  OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup));
211 }
#define GIST_SORTSUPPORT_PROC
Definition: gist.h:40
Assert(fmt[strlen(fmt) - 1] !='\n')
Oid * rd_opcintype
Definition: rel.h:204
Oid * rd_opfamily
Definition: rel.h:203
Form_pg_class rd_rel
Definition: rel.h:110
AttrNumber ssup_attno
Definition: sortsupport.h:81

References Assert(), SortSupportData::comparator, elog(), ERROR, get_opfamily_proc(), GIST_SORTSUPPORT_PROC, OidFunctionCall1, OidIsValid, PointerGetDatum(), RelationData::rd_opcintype, RelationData::rd_opfamily, RelationData::rd_rel, SortSupportData::ssup_attno, and SortSupportData::ssup_reverse.

Referenced by tuplesort_begin_index_gist().

◆ PrepareSortSupportFromIndexRel()

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

Definition at line 162 of file sortsupport.c.

164 {
165  Oid opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1];
166  Oid opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1];
167 
168  Assert(ssup->comparator == NULL);
169 
170  if (indexRel->rd_rel->relam != BTREE_AM_OID)
171  elog(ERROR, "unexpected non-btree AM: %u", indexRel->rd_rel->relam);
172  if (strategy != BTGreaterStrategyNumber &&
173  strategy != BTLessStrategyNumber)
174  elog(ERROR, "unexpected sort support strategy: %d", strategy);
175  ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
176 
177  FinishSortSupportFunction(opfamily, opcintype, ssup);
178 }
static void FinishSortSupportFunction(Oid opfamily, Oid opcintype, SortSupport ssup)
Definition: sortsupport.c:95
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define BTLessStrategyNumber
Definition: stratnum.h:29

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(), tuplesort_begin_cluster(), and tuplesort_begin_index_btree().

◆ PrepareSortSupportFromOrderingOp()

void PrepareSortSupportFromOrderingOp ( Oid  orderingOp,
SortSupport  ssup 
)

Definition at line 135 of file sortsupport.c.

136 {
137  Oid opfamily;
138  Oid opcintype;
139  int16 strategy;
140 
141  Assert(ssup->comparator == NULL);
142 
143  /* Find the operator in pg_amop */
144  if (!get_ordering_op_properties(orderingOp, &opfamily, &opcintype,
145  &strategy))
146  elog(ERROR, "operator %u is not a valid ordering operator",
147  orderingOp);
148  ssup->ssup_reverse = (strategy == BTGreaterStrategyNumber);
149 
150  FinishSortSupportFunction(opfamily, opcintype, ssup);
151 }
signed short int16
Definition: c.h:429
bool get_ordering_op_properties(Oid opno, Oid *opfamily, Oid *opcintype, int16 *strategy)
Definition: lsyscache.c:206

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

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