PostgreSQL Source Code  git master
amvalidate.c File Reference
#include "postgres.h"
#include "access/amvalidate.h"
#include "access/htup_details.h"
#include "catalog/pg_am.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "parser/parse_coerce.h"
#include "utils/syscache.h"
Include dependency graph for amvalidate.c:

Go to the source code of this file.

Functions

Listidentify_opfamily_groups (CatCList *oprlist, CatCList *proclist)
 
bool check_amproc_signature (Oid funcid, Oid restype, bool exact, int minargs, int maxargs,...)
 
bool check_amoptsproc_signature (Oid funcid)
 
bool check_amop_signature (Oid opno, Oid restype, Oid lefttype, Oid righttype)
 
bool opfamily_can_sort_type (Oid opfamilyoid, Oid datatypeoid)
 

Function Documentation

◆ check_amop_signature()

bool check_amop_signature ( Oid  opno,
Oid  restype,
Oid  lefttype,
Oid  righttype 
)

Definition at line 205 of file amvalidate.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, OPEROID, ReleaseSysCache(), and SearchSysCache1().

Referenced by blvalidate(), brinvalidate(), btvalidate(), ginvalidate(), gistvalidate(), hashvalidate(), and spgvalidate().

206 {
207  bool result = true;
208  HeapTuple tp;
209  Form_pg_operator opform;
210 
212  if (!HeapTupleIsValid(tp)) /* shouldn't happen */
213  elog(ERROR, "cache lookup failed for operator %u", opno);
214  opform = (Form_pg_operator) GETSTRUCT(tp);
215 
216  if (opform->oprresult != restype || opform->oprkind != 'b' ||
217  opform->oprleft != lefttype || opform->oprright != righttype)
218  result = false;
219 
220  ReleaseSysCache(tp);
221  return result;
222 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
#define elog(elevel,...)
Definition: elog.h:214

◆ check_amoptsproc_signature()

bool check_amoptsproc_signature ( Oid  funcid)

Definition at line 191 of file amvalidate.c.

References check_amproc_signature().

Referenced by blvalidate(), brinvalidate(), btvalidate(), ginvalidate(), gistvalidate(), hashvalidate(), and spgvalidate().

192 {
193  return check_amproc_signature(funcid, VOIDOID, true, 1, 1, INTERNALOID);
194 }
bool check_amproc_signature(Oid funcid, Oid restype, bool exact, int minargs, int maxargs,...)
Definition: amvalidate.c:151

◆ check_amproc_signature()

bool check_amproc_signature ( Oid  funcid,
Oid  restype,
bool  exact,
int  minargs,
int  maxargs,
  ... 
)

Definition at line 151 of file amvalidate.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, i, IsBinaryCoercible(), ObjectIdGetDatum, PROCOID, ReleaseSysCache(), and SearchSysCache1().

Referenced by blvalidate(), brinvalidate(), btvalidate(), check_amoptsproc_signature(), ginvalidate(), gistvalidate(), and spgvalidate().

153 {
154  bool result = true;
155  HeapTuple tp;
156  Form_pg_proc procform;
157  va_list ap;
158  int i;
159 
161  if (!HeapTupleIsValid(tp))
162  elog(ERROR, "cache lookup failed for function %u", funcid);
163  procform = (Form_pg_proc) GETSTRUCT(tp);
164 
165  if (procform->prorettype != restype || procform->proretset ||
166  procform->pronargs < minargs || procform->pronargs > maxargs)
167  result = false;
168 
169  va_start(ap, maxargs);
170  for (i = 0; i < maxargs; i++)
171  {
172  Oid argtype = va_arg(ap, Oid);
173 
174  if (i >= procform->pronargs)
175  continue;
176  if (exact ? (argtype != procform->proargtypes.values[i]) :
177  !IsBinaryCoercible(argtype, procform->proargtypes.values[i]))
178  result = false;
179  }
180  va_end(ap);
181 
182  ReleaseSysCache(tp);
183  return result;
184 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool IsBinaryCoercible(Oid srctype, Oid targettype)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:133
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214
int i

◆ identify_opfamily_groups()

List* identify_opfamily_groups ( CatCList oprlist,
CatCList proclist 
)

Definition at line 42 of file amvalidate.c.

References elog, ERROR, OpFamilyOpFuncGroup::functionset, GETSTRUCT, lappend(), OpFamilyOpFuncGroup::lefttype, catclist::members, NIL, OpFamilyOpFuncGroup::operatorset, catclist::ordered, palloc(), OpFamilyOpFuncGroup::righttype, and catctup::tuple.

Referenced by blvalidate(), brinvalidate(), btvalidate(), ginvalidate(), gistvalidate(), hashvalidate(), and spgvalidate().

43 {
44  List *result = NIL;
45  OpFamilyOpFuncGroup *thisgroup;
46  Form_pg_amop oprform;
47  Form_pg_amproc procform;
48  int io,
49  ip;
50 
51  /* We need the lists to be ordered; should be true in normal operation */
52  if (!oprlist->ordered || !proclist->ordered)
53  elog(ERROR, "cannot validate operator family without ordered data");
54 
55  /*
56  * Advance through the lists concurrently. Thanks to the ordering, we
57  * should see all operators and functions of a given datatype pair
58  * consecutively.
59  */
60  thisgroup = NULL;
61  io = ip = 0;
62  if (io < oprlist->n_members)
63  {
64  oprform = (Form_pg_amop) GETSTRUCT(&oprlist->members[io]->tuple);
65  io++;
66  }
67  else
68  oprform = NULL;
69  if (ip < proclist->n_members)
70  {
71  procform = (Form_pg_amproc) GETSTRUCT(&proclist->members[ip]->tuple);
72  ip++;
73  }
74  else
75  procform = NULL;
76 
77  while (oprform || procform)
78  {
79  if (oprform && thisgroup &&
80  oprform->amoplefttype == thisgroup->lefttype &&
81  oprform->amoprighttype == thisgroup->righttype)
82  {
83  /* Operator belongs to current group; include it and advance */
84 
85  /* Ignore strategy numbers outside supported range */
86  if (oprform->amopstrategy > 0 && oprform->amopstrategy < 64)
87  thisgroup->operatorset |= ((uint64) 1) << oprform->amopstrategy;
88 
89  if (io < oprlist->n_members)
90  {
91  oprform = (Form_pg_amop) GETSTRUCT(&oprlist->members[io]->tuple);
92  io++;
93  }
94  else
95  oprform = NULL;
96  continue;
97  }
98 
99  if (procform && thisgroup &&
100  procform->amproclefttype == thisgroup->lefttype &&
101  procform->amprocrighttype == thisgroup->righttype)
102  {
103  /* Procedure belongs to current group; include it and advance */
104 
105  /* Ignore function numbers outside supported range */
106  if (procform->amprocnum > 0 && procform->amprocnum < 64)
107  thisgroup->functionset |= ((uint64) 1) << procform->amprocnum;
108 
109  if (ip < proclist->n_members)
110  {
111  procform = (Form_pg_amproc) GETSTRUCT(&proclist->members[ip]->tuple);
112  ip++;
113  }
114  else
115  procform = NULL;
116  continue;
117  }
118 
119  /* Time for a new group */
120  thisgroup = (OpFamilyOpFuncGroup *) palloc(sizeof(OpFamilyOpFuncGroup));
121  if (oprform &&
122  (!procform ||
123  (oprform->amoplefttype < procform->amproclefttype ||
124  (oprform->amoplefttype == procform->amproclefttype &&
125  oprform->amoprighttype < procform->amprocrighttype))))
126  {
127  thisgroup->lefttype = oprform->amoplefttype;
128  thisgroup->righttype = oprform->amoprighttype;
129  }
130  else
131  {
132  thisgroup->lefttype = procform->amproclefttype;
133  thisgroup->righttype = procform->amprocrighttype;
134  }
135  thisgroup->operatorset = thisgroup->functionset = 0;
136  result = lappend(result, thisgroup);
137  }
138 
139  return result;
140 }
#define NIL
Definition: pg_list.h:65
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ERROR
Definition: elog.h:43
List * lappend(List *list, void *datum)
Definition: list.c:321
bool ordered
Definition: catcache.h:174
void * palloc(Size size)
Definition: mcxt.c:949
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:88
#define elog(elevel,...)
Definition: elog.h:214
HeapTupleData tuple
Definition: catcache.h:121
Definition: pg_list.h:50

◆ opfamily_can_sort_type()

bool opfamily_can_sort_type ( Oid  opfamilyoid,
Oid  datatypeoid 
)

Definition at line 228 of file amvalidate.c.

References CLAAMNAMENSP, GETSTRUCT, i, catclist::members, catclist::n_members, ObjectIdGetDatum, ReleaseCatCacheList(), SearchSysCacheList1, and catctup::tuple.

Referenced by gistvalidate(), spgproperty(), and spgvalidate().

229 {
230  bool result = false;
231  CatCList *opclist;
232  int i;
233 
234  /*
235  * We search through all btree opclasses to see if one matches. This is a
236  * bit inefficient but there is no better index available. It also saves
237  * making an explicit check that the opfamily belongs to btree.
238  */
239  opclist = SearchSysCacheList1(CLAAMNAMENSP, ObjectIdGetDatum(BTREE_AM_OID));
240 
241  for (i = 0; i < opclist->n_members; i++)
242  {
243  HeapTuple classtup = &opclist->members[i]->tuple;
244  Form_pg_opclass classform = (Form_pg_opclass) GETSTRUCT(classtup);
245 
246  if (classform->opcfamily == opfamilyoid &&
247  classform->opcintype == datatypeoid)
248  {
249  result = true;
250  break;
251  }
252  }
253 
254  ReleaseCatCacheList(opclist);
255 
256  return result;
257 }
int n_members
Definition: catcache.h:176
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void ReleaseCatCacheList(CatCList *list)
Definition: catcache.c:1782
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:210
int i
HeapTupleData tuple
Definition: catcache.h:121
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83