PostgreSQL Source Code  git master
parse_oper.h File Reference
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
Include dependency graph for parse_oper.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef HeapTuple Operator
 

Functions

Oid LookupOperName (ParseState *pstate, List *opername, Oid oprleft, Oid oprright, bool noError, int location)
 
Oid LookupOperWithArgs (ObjectWithArgs *oper, bool noError)
 
Operator oper (ParseState *pstate, List *op, Oid arg1, Oid arg2, bool noError, int location)
 
Operator left_oper (ParseState *pstate, List *op, Oid arg, bool noError, int location)
 
Operator compatible_oper (ParseState *pstate, List *op, Oid arg1, Oid arg2, bool noError, int location)
 
void get_sort_group_operators (Oid argtype, bool needLT, bool needEQ, bool needGT, Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, bool *isHashable)
 
Oid compatible_oper_opid (List *op, Oid arg1, Oid arg2, bool noError)
 
Oid oprid (Operator op)
 
Oid oprfuncid (Operator op)
 
Exprmake_op (ParseState *pstate, List *opname, Node *ltree, Node *rtree, Node *last_srf, int location)
 
Exprmake_scalar_array_op (ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
 

Typedef Documentation

◆ Operator

Definition at line 22 of file parse_oper.h.

Function Documentation

◆ compatible_oper()

Operator compatible_oper ( ParseState pstate,
List op,
Oid  arg1,
Oid  arg2,
bool  noError,
int  location 
)

Definition at line 462 of file parse_oper.c.

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, IsBinaryCoercible(), op_signature_string(), oper(), parser_errposition(), and ReleaseSysCache().

Referenced by compatible_oper_opid().

464 {
465  Operator optup;
466  Form_pg_operator opform;
467 
468  /* oper() will find the best available match */
469  optup = oper(pstate, op, arg1, arg2, noError, location);
470  if (optup == (Operator) NULL)
471  return (Operator) NULL; /* must be noError case */
472 
473  /* but is it good enough? */
474  opform = (Form_pg_operator) GETSTRUCT(optup);
475  if (IsBinaryCoercible(arg1, opform->oprleft) &&
476  IsBinaryCoercible(arg2, opform->oprright))
477  return optup;
478 
479  /* nope... */
480  ReleaseSysCache(optup);
481 
482  if (!noError)
483  ereport(ERROR,
484  (errcode(ERRCODE_UNDEFINED_FUNCTION),
485  errmsg("operator requires run-time type coercion: %s",
486  op_signature_string(op, 'b', arg1, arg2)),
487  parser_errposition(pstate, location)));
488 
489  return (Operator) NULL;
490 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int errcode(int sqlerrcode)
Definition: elog.c:610
static const char * op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
Definition: parse_oper.c:614
#define ERROR
Definition: elog.h:43
bool IsBinaryCoercible(Oid srctype, Oid targettype)
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
int errmsg(const char *fmt,...)
Definition: elog.c:821
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:382

◆ compatible_oper_opid()

Oid compatible_oper_opid ( List op,
Oid  arg1,
Oid  arg2,
bool  noError 
)

Definition at line 499 of file parse_oper.c.

References compatible_oper(), InvalidOid, oprid(), and ReleaseSysCache().

Referenced by addTargetToSortList(), and ComputeIndexAttrs().

500 {
501  Operator optup;
502  Oid result;
503 
504  optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
505  if (optup != NULL)
506  {
507  result = oprid(optup);
508  ReleaseSysCache(optup);
509  return result;
510  }
511  return InvalidOid;
512 }
Oid oprid(Operator op)
Definition: parse_oper.c:250
unsigned int Oid
Definition: postgres_ext.h:31
Operator compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2, bool noError, int location)
Definition: parse_oper.c:462
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define InvalidOid
Definition: postgres_ext.h:36

◆ get_sort_group_operators()

void get_sort_group_operators ( Oid  argtype,
bool  needLT,
bool  needEQ,
bool  needGT,
Oid ltOpr,
Oid eqOpr,
Oid gtOpr,
bool isHashable 
)

Definition at line 192 of file parse_oper.c.

References TypeCacheEntry::eq_opr, ereport, errcode(), errhint(), errmsg(), ERROR, format_type_be(), TypeCacheEntry::gt_opr, TypeCacheEntry::hash_proc, lookup_type_cache(), TypeCacheEntry::lt_opr, OidIsValid, TYPECACHE_EQ_OPR, TYPECACHE_GT_OPR, TYPECACHE_HASH_PROC, and TYPECACHE_LT_OPR.

Referenced by addTargetToGroupList(), addTargetToSortList(), std_typanalyze(), and transformSetOperationTree().

196 {
197  TypeCacheEntry *typentry;
198  int cache_flags;
199  Oid lt_opr;
200  Oid eq_opr;
201  Oid gt_opr;
202  bool hashable;
203 
204  /*
205  * Look up the operators using the type cache.
206  *
207  * Note: the search algorithm used by typcache.c ensures that the results
208  * are consistent, ie all from matching opclasses.
209  */
210  if (isHashable != NULL)
213  else
215 
216  typentry = lookup_type_cache(argtype, cache_flags);
217  lt_opr = typentry->lt_opr;
218  eq_opr = typentry->eq_opr;
219  gt_opr = typentry->gt_opr;
220  hashable = OidIsValid(typentry->hash_proc);
221 
222  /* Report errors if needed */
223  if ((needLT && !OidIsValid(lt_opr)) ||
224  (needGT && !OidIsValid(gt_opr)))
225  ereport(ERROR,
226  (errcode(ERRCODE_UNDEFINED_FUNCTION),
227  errmsg("could not identify an ordering operator for type %s",
228  format_type_be(argtype)),
229  errhint("Use an explicit ordering operator or modify the query.")));
230  if (needEQ && !OidIsValid(eq_opr))
231  ereport(ERROR,
232  (errcode(ERRCODE_UNDEFINED_FUNCTION),
233  errmsg("could not identify an equality operator for type %s",
234  format_type_be(argtype))));
235 
236  /* Return results as needed */
237  if (ltOpr)
238  *ltOpr = lt_opr;
239  if (eqOpr)
240  *eqOpr = eq_opr;
241  if (gtOpr)
242  *gtOpr = gt_opr;
243  if (isHashable)
244  *isHashable = hashable;
245 }
int errhint(const char *fmt,...)
Definition: elog.c:1068
#define TYPECACHE_EQ_OPR
Definition: typcache.h:130
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
#define ERROR
Definition: elog.h:43
#define TYPECACHE_GT_OPR
Definition: typcache.h:132
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:331
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define TYPECACHE_LT_OPR
Definition: typcache.h:131
#define TYPECACHE_HASH_PROC
Definition: typcache.h:134

◆ left_oper()

Operator left_oper ( ParseState pstate,
List op,
Oid  arg,
bool  noError,
int  location 
)

Definition at line 530 of file parse_oper.c.

References _FuncCandidateList::args, find_oper_cache_entry(), FUNCDETAIL_NOTFOUND, HeapTupleIsValid, InvalidOid, sort-test::key, make_oper_cache_entry(), make_oper_cache_key(), _FuncCandidateList::next, ObjectIdGetDatum, OidIsValid, op_error(), oper_select_candidate(), OpernameGetCandidates(), OpernameGetOprid(), OPEROID, and SearchSysCache1().

Referenced by generate_operator_name(), and make_op().

531 {
532  Oid operOid;
534  bool key_ok;
536  HeapTuple tup = NULL;
537 
538  /*
539  * Try to find the mapping in the lookaside cache.
540  */
541  key_ok = make_oper_cache_key(pstate, &key, op, InvalidOid, arg, location);
542 
543  if (key_ok)
544  {
545  operOid = find_oper_cache_entry(&key);
546  if (OidIsValid(operOid))
547  {
548  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
549  if (HeapTupleIsValid(tup))
550  return (Operator) tup;
551  }
552  }
553 
554  /*
555  * First try for an "exact" match.
556  */
557  operOid = OpernameGetOprid(op, InvalidOid, arg);
558  if (!OidIsValid(operOid))
559  {
560  /*
561  * Otherwise, search for the most suitable candidate.
562  */
563  FuncCandidateList clist;
564 
565  /* Get prefix operators of given name */
566  clist = OpernameGetCandidates(op, 'l', false);
567 
568  /* No operators found? Then fail... */
569  if (clist != NULL)
570  {
571  /*
572  * The returned list has args in the form (0, oprright). Move the
573  * useful data into args[0] to keep oper_select_candidate simple.
574  * XXX we are assuming here that we may scribble on the list!
575  */
576  FuncCandidateList clisti;
577 
578  for (clisti = clist; clisti != NULL; clisti = clisti->next)
579  {
580  clisti->args[0] = clisti->args[1];
581  }
582 
583  /*
584  * We must run oper_select_candidate even if only one candidate,
585  * otherwise we may falsely return a non-type-compatible operator.
586  */
587  fdresult = oper_select_candidate(1, &arg, clist, &operOid);
588  }
589  }
590 
591  if (OidIsValid(operOid))
592  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
593 
594  if (HeapTupleIsValid(tup))
595  {
596  if (key_ok)
597  make_oper_cache_entry(&key, operOid);
598  }
599  else if (!noError)
600  op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location);
601 
602  return (Operator) tup;
603 }
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
Definition: namespace.c:1586
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1483
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FuncDetailCode
Definition: parse_func.h:22
static Oid find_oper_cache_entry(OprCacheKey *key)
Definition: parse_oper.c:993
struct _FuncCandidateList * next
Definition: namespace.h:30
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
static void op_error(ParseState *pstate, List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult, int location)
Definition: parse_oper.c:634
static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
Definition: parse_oper.c:1033
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static bool make_oper_cache_key(ParseState *pstate, OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId, int location)
Definition: parse_oper.c:949
static FuncDetailCode oper_select_candidate(int nargs, Oid *input_typeids, FuncCandidateList candidates, Oid *operOid)
Definition: parse_oper.c:324
void * arg

◆ LookupOperName()

Oid LookupOperName ( ParseState pstate,
List opername,
Oid  oprleft,
Oid  oprright,
bool  noError,
int  location 
)

Definition at line 101 of file parse_oper.c.

References ereport, errcode(), errmsg(), ERROR, InvalidOid, OidIsValid, op_signature_string(), OpernameGetOprid(), and parser_errposition().

Referenced by AggregateCreate(), DefineOpClass(), LookupOperWithArgs(), and OperatorLookup().

103 {
104  Oid result;
105 
106  result = OpernameGetOprid(opername, oprleft, oprright);
107  if (OidIsValid(result))
108  return result;
109 
110  /* we don't use op_error here because only an exact match is wanted */
111  if (!noError)
112  {
113  char oprkind;
114 
115  if (!OidIsValid(oprleft))
116  oprkind = 'l';
117  else if (OidIsValid(oprright))
118  oprkind = 'b';
119  else
120  {
121  ereport(ERROR,
122  (errcode(ERRCODE_SYNTAX_ERROR),
123  errmsg("postfix operators are not supported"),
124  parser_errposition(pstate, location)));
125  oprkind = 0; /* keep compiler quiet */
126  }
127 
128  ereport(ERROR,
129  (errcode(ERRCODE_UNDEFINED_FUNCTION),
130  errmsg("operator does not exist: %s",
131  op_signature_string(opername, oprkind,
132  oprleft, oprright)),
133  parser_errposition(pstate, location)));
134  }
135 
136  return InvalidOid;
137 }
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
static const char * op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
Definition: parse_oper.c:614
#define OidIsValid(objectId)
Definition: c.h:652
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1483
#define ERROR
Definition: elog.h:43
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ LookupOperWithArgs()

Oid LookupOperWithArgs ( ObjectWithArgs oper,
bool  noError 
)

Definition at line 145 of file parse_oper.c.

References Assert, InvalidOid, linitial, list_length(), LookupOperName(), LookupTypeNameOid(), lsecond, ObjectWithArgs::objargs, and ObjectWithArgs::objname.

Referenced by AlterOperator(), AlterOpFamilyAdd(), DefineOpClass(), and get_object_address().

146 {
147  TypeName *oprleft,
148  *oprright;
149  Oid leftoid,
150  rightoid;
151 
152  Assert(list_length(oper->objargs) == 2);
153  oprleft = linitial(oper->objargs);
154  oprright = lsecond(oper->objargs);
155 
156  if (oprleft == NULL)
157  leftoid = InvalidOid;
158  else
159  leftoid = LookupTypeNameOid(NULL, oprleft, noError);
160 
161  if (oprright == NULL)
162  rightoid = InvalidOid;
163  else
164  rightoid = LookupTypeNameOid(NULL, oprright, noError);
165 
166  return LookupOperName(NULL, oper->objname, leftoid, rightoid,
167  noError, -1);
168 }
Oid LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright, bool noError, int location)
Definition: parse_oper.c:101
unsigned int Oid
Definition: postgres_ext.h:31
#define lsecond(l)
Definition: pg_list.h:179
#define linitial(l)
Definition: pg_list.h:174
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:746
static int list_length(const List *l)
Definition: pg_list.h:149
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
Definition: parse_type.c:232

◆ make_op()

Expr* make_op ( ParseState pstate,
List opname,
Node ltree,
Node rtree,
Node last_srf,
int  location 
)

Definition at line 672 of file parse_oper.c.

References generate_unaccent_rules::args, OpExpr::args, check_srf_call_placement(), enforce_generic_type_consistency(), ereport, errcode(), errmsg(), ERROR, exprType(), get_func_retset(), GETSTRUCT, InvalidOid, left_oper(), list_make1, list_make2, OpExpr::location, make_fn_arguments(), makeNode, op_signature_string(), oper(), OpExpr::opfuncid, OpExpr::opno, OpExpr::opresulttype, OpExpr::opretset, oprid(), ParseState::p_last_srf, parser_errposition(), RegProcedureIsValid, and ReleaseSysCache().

Referenced by make_distinct_op(), make_row_comparison_op(), transformAExprIn(), transformAExprNullIf(), and transformAExprOp().

674 {
675  Oid ltypeId,
676  rtypeId;
677  Operator tup;
678  Form_pg_operator opform;
679  Oid actual_arg_types[2];
680  Oid declared_arg_types[2];
681  int nargs;
682  List *args;
683  Oid rettype;
684  OpExpr *result;
685 
686  /* Check it's not a postfix operator */
687  if (rtree == NULL)
688  ereport(ERROR,
689  (errcode(ERRCODE_SYNTAX_ERROR),
690  errmsg("postfix operators are not supported")));
691 
692  /* Select the operator */
693  if (ltree == NULL)
694  {
695  /* prefix operator */
696  rtypeId = exprType(rtree);
697  ltypeId = InvalidOid;
698  tup = left_oper(pstate, opname, rtypeId, false, location);
699  }
700  else
701  {
702  /* otherwise, binary operator */
703  ltypeId = exprType(ltree);
704  rtypeId = exprType(rtree);
705  tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
706  }
707 
708  opform = (Form_pg_operator) GETSTRUCT(tup);
709 
710  /* Check it's not a shell */
711  if (!RegProcedureIsValid(opform->oprcode))
712  ereport(ERROR,
713  (errcode(ERRCODE_UNDEFINED_FUNCTION),
714  errmsg("operator is only a shell: %s",
715  op_signature_string(opname,
716  opform->oprkind,
717  opform->oprleft,
718  opform->oprright)),
719  parser_errposition(pstate, location)));
720 
721  /* Do typecasting and build the expression tree */
722  if (ltree == NULL)
723  {
724  /* prefix operator */
725  args = list_make1(rtree);
726  actual_arg_types[0] = rtypeId;
727  declared_arg_types[0] = opform->oprright;
728  nargs = 1;
729  }
730  else
731  {
732  /* otherwise, binary operator */
733  args = list_make2(ltree, rtree);
734  actual_arg_types[0] = ltypeId;
735  actual_arg_types[1] = rtypeId;
736  declared_arg_types[0] = opform->oprleft;
737  declared_arg_types[1] = opform->oprright;
738  nargs = 2;
739  }
740 
741  /*
742  * enforce consistency with polymorphic argument and return types,
743  * possibly adjusting return type or declared_arg_types (which will be
744  * used as the cast destination by make_fn_arguments)
745  */
746  rettype = enforce_generic_type_consistency(actual_arg_types,
747  declared_arg_types,
748  nargs,
749  opform->oprresult,
750  false);
751 
752  /* perform the necessary typecasting of arguments */
753  make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
754 
755  /* and build the expression node */
756  result = makeNode(OpExpr);
757  result->opno = oprid(tup);
758  result->opfuncid = opform->oprcode;
759  result->opresulttype = rettype;
760  result->opretset = get_func_retset(opform->oprcode);
761  /* opcollid and inputcollid will be set by parse_collate.c */
762  result->args = args;
763  result->location = location;
764 
765  /* if it returns a set, check that's OK */
766  if (result->opretset)
767  {
768  check_srf_call_placement(pstate, last_srf, location);
769  /* ... and remember it for error checks at higher levels */
770  pstate->p_last_srf = (Node *) result;
771  }
772 
773  ReleaseSysCache(tup);
774 
775  return (Expr *) result;
776 }
#define list_make2(x1, x2)
Definition: pg_list.h:208
Oid enforce_generic_type_consistency(const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, bool allow_poly)
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid oprid(Operator op)
Definition: parse_oper.c:250
Definition: nodes.h:528
int errcode(int sqlerrcode)
Definition: elog.c:610
void make_fn_arguments(ParseState *pstate, List *fargs, Oid *actual_arg_types, Oid *declared_arg_types)
Definition: parse_func.c:1810
unsigned int Oid
Definition: postgres_ext.h:31
static const char * op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
Definition: parse_oper.c:614
#define list_make1(x1)
Definition: pg_list.h:206
Oid opresulttype
Definition: primnodes.h:518
#define ERROR
Definition: elog.h:43
Operator left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
Definition: parse_oper.c:530
int location
Definition: primnodes.h:523
#define RegProcedureIsValid(p)
Definition: c.h:654
bool get_func_retset(Oid funcid)
Definition: lsyscache.c:1654
Node * p_last_srf
Definition: parse_node.h:212
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Oid opfuncid
Definition: primnodes.h:517
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define makeNode(_type_)
Definition: nodes.h:576
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
int errmsg(const char *fmt,...)
Definition: elog.c:821
void check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
Definition: parse_func.c:2382
Oid opno
Definition: primnodes.h:516
List * args
Definition: primnodes.h:522
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:382
Definition: pg_list.h:50
bool opretset
Definition: primnodes.h:519

◆ make_scalar_array_op()

Expr* make_scalar_array_op ( ParseState pstate,
List opname,
bool  useOr,
Node ltree,
Node rtree,
int  location 
)

Definition at line 783 of file parse_oper.c.

References generate_unaccent_rules::args, ScalarArrayOpExpr::args, enforce_generic_type_consistency(), ereport, errcode(), errmsg(), ERROR, exprType(), format_type_be(), get_array_type(), get_base_element_type(), get_func_retset(), GETSTRUCT, list_make2, ScalarArrayOpExpr::location, make_fn_arguments(), makeNode, OidIsValid, op_signature_string(), oper(), ScalarArrayOpExpr::opfuncid, ScalarArrayOpExpr::opno, oprid(), parser_errposition(), RegProcedureIsValid, ReleaseSysCache(), and ScalarArrayOpExpr::useOr.

Referenced by transformAExprIn(), transformAExprOpAll(), and transformAExprOpAny().

787 {
788  Oid ltypeId,
789  rtypeId,
790  atypeId,
791  res_atypeId;
792  Operator tup;
793  Form_pg_operator opform;
794  Oid actual_arg_types[2];
795  Oid declared_arg_types[2];
796  List *args;
797  Oid rettype;
798  ScalarArrayOpExpr *result;
799 
800  ltypeId = exprType(ltree);
801  atypeId = exprType(rtree);
802 
803  /*
804  * The right-hand input of the operator will be the element type of the
805  * array. However, if we currently have just an untyped literal on the
806  * right, stay with that and hope we can resolve the operator.
807  */
808  if (atypeId == UNKNOWNOID)
809  rtypeId = UNKNOWNOID;
810  else
811  {
812  rtypeId = get_base_element_type(atypeId);
813  if (!OidIsValid(rtypeId))
814  ereport(ERROR,
815  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
816  errmsg("op ANY/ALL (array) requires array on right side"),
817  parser_errposition(pstate, location)));
818  }
819 
820  /* Now resolve the operator */
821  tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
822  opform = (Form_pg_operator) GETSTRUCT(tup);
823 
824  /* Check it's not a shell */
825  if (!RegProcedureIsValid(opform->oprcode))
826  ereport(ERROR,
827  (errcode(ERRCODE_UNDEFINED_FUNCTION),
828  errmsg("operator is only a shell: %s",
829  op_signature_string(opname,
830  opform->oprkind,
831  opform->oprleft,
832  opform->oprright)),
833  parser_errposition(pstate, location)));
834 
835  args = list_make2(ltree, rtree);
836  actual_arg_types[0] = ltypeId;
837  actual_arg_types[1] = rtypeId;
838  declared_arg_types[0] = opform->oprleft;
839  declared_arg_types[1] = opform->oprright;
840 
841  /*
842  * enforce consistency with polymorphic argument and return types,
843  * possibly adjusting return type or declared_arg_types (which will be
844  * used as the cast destination by make_fn_arguments)
845  */
846  rettype = enforce_generic_type_consistency(actual_arg_types,
847  declared_arg_types,
848  2,
849  opform->oprresult,
850  false);
851 
852  /*
853  * Check that operator result is boolean
854  */
855  if (rettype != BOOLOID)
856  ereport(ERROR,
857  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
858  errmsg("op ANY/ALL (array) requires operator to yield boolean"),
859  parser_errposition(pstate, location)));
860  if (get_func_retset(opform->oprcode))
861  ereport(ERROR,
862  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
863  errmsg("op ANY/ALL (array) requires operator not to return a set"),
864  parser_errposition(pstate, location)));
865 
866  /*
867  * Now switch back to the array type on the right, arranging for any
868  * needed cast to be applied. Beware of polymorphic operators here;
869  * enforce_generic_type_consistency may or may not have replaced a
870  * polymorphic type with a real one.
871  */
872  if (IsPolymorphicType(declared_arg_types[1]))
873  {
874  /* assume the actual array type is OK */
875  res_atypeId = atypeId;
876  }
877  else
878  {
879  res_atypeId = get_array_type(declared_arg_types[1]);
880  if (!OidIsValid(res_atypeId))
881  ereport(ERROR,
882  (errcode(ERRCODE_UNDEFINED_OBJECT),
883  errmsg("could not find array type for data type %s",
884  format_type_be(declared_arg_types[1])),
885  parser_errposition(pstate, location)));
886  }
887  actual_arg_types[1] = atypeId;
888  declared_arg_types[1] = res_atypeId;
889 
890  /* perform the necessary typecasting of arguments */
891  make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
892 
893  /* and build the expression node */
894  result = makeNode(ScalarArrayOpExpr);
895  result->opno = oprid(tup);
896  result->opfuncid = opform->oprcode;
897  result->useOr = useOr;
898  /* inputcollid will be set by parse_collate.c */
899  result->args = args;
900  result->location = location;
901 
902  ReleaseSysCache(tup);
903 
904  return (Expr *) result;
905 }
#define list_make2(x1, x2)
Definition: pg_list.h:208
Oid enforce_generic_type_consistency(const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, bool allow_poly)
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid oprid(Operator op)
Definition: parse_oper.c:250
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2664
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
void make_fn_arguments(ParseState *pstate, List *fargs, Oid *actual_arg_types, Oid *declared_arg_types)
Definition: parse_func.c:1810
unsigned int Oid
Definition: postgres_ext.h:31
static const char * op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
Definition: parse_oper.c:614
#define OidIsValid(objectId)
Definition: c.h:652
#define ERROR
Definition: elog.h:43
#define RegProcedureIsValid(p)
Definition: c.h:654
bool get_func_retset(Oid funcid)
Definition: lsyscache.c:1654
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define makeNode(_type_)
Definition: nodes.h:576
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2709
int errmsg(const char *fmt,...)
Definition: elog.c:821
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:382
Definition: pg_list.h:50

◆ oper()

Operator oper ( ParseState pstate,
List op,
Oid  arg1,
Oid  arg2,
bool  noError,
int  location 
)

Definition at line 382 of file parse_oper.c.

References binary_oper_exact(), find_oper_cache_entry(), FUNCDETAIL_NOTFOUND, HeapTupleIsValid, InvalidOid, sort-test::key, make_oper_cache_entry(), make_oper_cache_key(), ObjectIdGetDatum, OidIsValid, op_error(), oper_select_candidate(), OpernameGetCandidates(), OPEROID, and SearchSysCache1().

Referenced by compatible_oper(), generate_operator_name(), make_op(), make_scalar_array_op(), makeOperatorDependencies(), pushOperator(), tsquery_opr_selec(), and tsqueryrecv().

384 {
385  Oid operOid;
387  bool key_ok;
389  HeapTuple tup = NULL;
390 
391  /*
392  * Try to find the mapping in the lookaside cache.
393  */
394  key_ok = make_oper_cache_key(pstate, &key, opname, ltypeId, rtypeId, location);
395 
396  if (key_ok)
397  {
398  operOid = find_oper_cache_entry(&key);
399  if (OidIsValid(operOid))
400  {
401  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
402  if (HeapTupleIsValid(tup))
403  return (Operator) tup;
404  }
405  }
406 
407  /*
408  * First try for an "exact" match.
409  */
410  operOid = binary_oper_exact(opname, ltypeId, rtypeId);
411  if (!OidIsValid(operOid))
412  {
413  /*
414  * Otherwise, search for the most suitable candidate.
415  */
416  FuncCandidateList clist;
417 
418  /* Get binary operators of given name */
419  clist = OpernameGetCandidates(opname, 'b', false);
420 
421  /* No operators found? Then fail... */
422  if (clist != NULL)
423  {
424  /*
425  * Unspecified type for one of the arguments? then use the other
426  * (XXX this is probably dead code?)
427  */
428  Oid inputOids[2];
429 
430  if (rtypeId == InvalidOid)
431  rtypeId = ltypeId;
432  else if (ltypeId == InvalidOid)
433  ltypeId = rtypeId;
434  inputOids[0] = ltypeId;
435  inputOids[1] = rtypeId;
436  fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
437  }
438  }
439 
440  if (OidIsValid(operOid))
441  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
442 
443  if (HeapTupleIsValid(tup))
444  {
445  if (key_ok)
446  make_oper_cache_entry(&key, operOid);
447  }
448  else if (!noError)
449  op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location);
450 
451  return (Operator) tup;
452 }
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
Definition: namespace.c:1586
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FuncDetailCode
Definition: parse_func.h:22
static Oid find_oper_cache_entry(OprCacheKey *key)
Definition: parse_oper.c:993
static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2)
Definition: parse_oper.c:274
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
static void op_error(ParseState *pstate, List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult, int location)
Definition: parse_oper.c:634
static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
Definition: parse_oper.c:1033
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static bool make_oper_cache_key(ParseState *pstate, OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId, int location)
Definition: parse_oper.c:949
static FuncDetailCode oper_select_candidate(int nargs, Oid *input_typeids, FuncCandidateList candidates, Oid *operOid)
Definition: parse_oper.c:324

◆ oprfuncid()

Oid oprfuncid ( Operator  op)

Definition at line 257 of file parse_oper.c.

References GETSTRUCT.

258 {
260 
261  return pgopform->oprcode;
262 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83

◆ oprid()

Oid oprid ( Operator  op)

Definition at line 250 of file parse_oper.c.

References GETSTRUCT.

Referenced by compatible_oper_opid(), dumpOpr(), generate_operator_name(), inclusion_get_strategy_procinfo(), make_op(), make_scalar_array_op(), minmax_get_strategy_procinfo(), OperatorIsVisible(), regoperatorout(), and regoperout().

251 {
252  return ((Form_pg_operator) GETSTRUCT(op))->oid;
253 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83