PostgreSQL Source Code  git master
parse_oper.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * parse_oper.c
4  * handle operator things for parser
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/parser/parse_oper.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include "access/htup_details.h"
19 #include "catalog/pg_operator.h"
20 #include "catalog/pg_type.h"
21 #include "lib/stringinfo.h"
22 #include "nodes/nodeFuncs.h"
23 #include "parser/parse_coerce.h"
24 #include "parser/parse_func.h"
25 #include "parser/parse_oper.h"
26 #include "parser/parse_type.h"
27 #include "utils/builtins.h"
28 #include "utils/inval.h"
29 #include "utils/lsyscache.h"
30 #include "utils/syscache.h"
31 #include "utils/typcache.h"
32 
33 
34 /*
35  * The lookup key for the operator lookaside hash table. Unused bits must be
36  * zeroes to ensure hashing works consistently --- in particular, oprname
37  * must be zero-padded and any unused entries in search_path must be zero.
38  *
39  * search_path contains the actual search_path with which the entry was
40  * derived (minus temp namespace if any), or else the single specified
41  * schema OID if we are looking up an explicitly-qualified operator name.
42  *
43  * search_path has to be fixed-length since the hashtable code insists on
44  * fixed-size keys. If your search path is longer than that, we just punt
45  * and don't cache anything.
46  */
47 
48 /* If your search_path is longer than this, sucks to be you ... */
49 #define MAX_CACHED_PATH_LEN 16
50 
51 typedef struct OprCacheKey
52 {
54  Oid left_arg; /* Left input OID, or 0 if prefix op */
55  Oid right_arg; /* Right input OID */
58 
59 typedef struct OprCacheEntry
60 {
61  /* the hash lookup key MUST BE FIRST */
63 
64  Oid opr_oid; /* OID of the resolved operator */
66 
67 
68 static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2);
69 static FuncDetailCode oper_select_candidate(int nargs,
70  Oid *input_typeids,
71  FuncCandidateList candidates,
72  Oid *operOid);
73 static void op_error(ParseState *pstate, List *op,
74  Oid arg1, Oid arg2,
75  FuncDetailCode fdresult, int location);
76 static bool make_oper_cache_key(ParseState *pstate, OprCacheKey *key,
77  List *opname, Oid ltypeId, Oid rtypeId,
78  int location);
80 static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid);
81 static void InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue);
82 
83 
84 /*
85  * LookupOperName
86  * Given a possibly-qualified operator name and exact input datatypes,
87  * look up the operator.
88  *
89  * Pass oprleft = InvalidOid for a prefix op.
90  *
91  * If the operator name is not schema-qualified, it is sought in the current
92  * namespace search path.
93  *
94  * If the operator is not found, we return InvalidOid if noError is true,
95  * else raise an error. pstate and location are used only to report the
96  * error position; pass NULL/-1 if not available.
97  */
98 Oid
99 LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
100  bool noError, int location)
101 {
102  Oid result;
103 
104  result = OpernameGetOprid(opername, oprleft, oprright);
105  if (OidIsValid(result))
106  return result;
107 
108  /* we don't use op_error here because only an exact match is wanted */
109  if (!noError)
110  {
111  if (!OidIsValid(oprright))
112  ereport(ERROR,
113  (errcode(ERRCODE_SYNTAX_ERROR),
114  errmsg("postfix operators are not supported"),
115  parser_errposition(pstate, location)));
116 
117  ereport(ERROR,
118  (errcode(ERRCODE_UNDEFINED_FUNCTION),
119  errmsg("operator does not exist: %s",
120  op_signature_string(opername, oprleft, oprright)),
121  parser_errposition(pstate, location)));
122  }
123 
124  return InvalidOid;
125 }
126 
127 /*
128  * LookupOperWithArgs
129  * Like LookupOperName, but the argument types are specified by
130  * a ObjectWithArgs node.
131  */
132 Oid
134 {
135  TypeName *oprleft,
136  *oprright;
137  Oid leftoid,
138  rightoid;
139 
140  Assert(list_length(oper->objargs) == 2);
141  oprleft = linitial_node(TypeName, oper->objargs);
142  oprright = lsecond_node(TypeName, oper->objargs);
143 
144  if (oprleft == NULL)
145  leftoid = InvalidOid;
146  else
147  leftoid = LookupTypeNameOid(NULL, oprleft, noError);
148 
149  if (oprright == NULL)
150  rightoid = InvalidOid;
151  else
152  rightoid = LookupTypeNameOid(NULL, oprright, noError);
153 
154  return LookupOperName(NULL, oper->objname, leftoid, rightoid,
155  noError, -1);
156 }
157 
158 /*
159  * get_sort_group_operators - get default sorting/grouping operators for type
160  *
161  * We fetch the "<", "=", and ">" operators all at once to reduce lookup
162  * overhead (knowing that most callers will be interested in at least two).
163  * However, a given datatype might have only an "=" operator, if it is
164  * hashable but not sortable. (Other combinations of present and missing
165  * operators shouldn't happen, unless the system catalogs are messed up.)
166  *
167  * If an operator is missing and the corresponding needXX flag is true,
168  * throw a standard error message, else return InvalidOid.
169  *
170  * In addition to the operator OIDs themselves, this function can identify
171  * whether the "=" operator is hashable.
172  *
173  * Callers can pass NULL pointers for any results they don't care to get.
174  *
175  * Note: the results are guaranteed to be exact or binary-compatible matches,
176  * since most callers are not prepared to cope with adding any run-time type
177  * coercion steps.
178  */
179 void
181  bool needLT, bool needEQ, bool needGT,
182  Oid *ltOpr, Oid *eqOpr, Oid *gtOpr,
183  bool *isHashable)
184 {
185  TypeCacheEntry *typentry;
186  int cache_flags;
187  Oid lt_opr;
188  Oid eq_opr;
189  Oid gt_opr;
190  bool hashable;
191 
192  /*
193  * Look up the operators using the type cache.
194  *
195  * Note: the search algorithm used by typcache.c ensures that the results
196  * are consistent, ie all from matching opclasses.
197  */
198  if (isHashable != NULL)
201  else
203 
204  typentry = lookup_type_cache(argtype, cache_flags);
205  lt_opr = typentry->lt_opr;
206  eq_opr = typentry->eq_opr;
207  gt_opr = typentry->gt_opr;
208  hashable = OidIsValid(typentry->hash_proc);
209 
210  /* Report errors if needed */
211  if ((needLT && !OidIsValid(lt_opr)) ||
212  (needGT && !OidIsValid(gt_opr)))
213  ereport(ERROR,
214  (errcode(ERRCODE_UNDEFINED_FUNCTION),
215  errmsg("could not identify an ordering operator for type %s",
216  format_type_be(argtype)),
217  errhint("Use an explicit ordering operator or modify the query.")));
218  if (needEQ && !OidIsValid(eq_opr))
219  ereport(ERROR,
220  (errcode(ERRCODE_UNDEFINED_FUNCTION),
221  errmsg("could not identify an equality operator for type %s",
222  format_type_be(argtype))));
223 
224  /* Return results as needed */
225  if (ltOpr)
226  *ltOpr = lt_opr;
227  if (eqOpr)
228  *eqOpr = eq_opr;
229  if (gtOpr)
230  *gtOpr = gt_opr;
231  if (isHashable)
232  *isHashable = hashable;
233 }
234 
235 
236 /* given operator tuple, return the operator OID */
237 Oid
239 {
240  return ((Form_pg_operator) GETSTRUCT(op))->oid;
241 }
242 
243 /* given operator tuple, return the underlying function's OID */
244 Oid
246 {
248 
249  return pgopform->oprcode;
250 }
251 
252 
253 /* binary_oper_exact()
254  * Check for an "exact" match to the specified operand types.
255  *
256  * If one operand is an unknown literal, assume it should be taken to be
257  * the same type as the other operand for this purpose. Also, consider
258  * the possibility that the other operand is a domain type that needs to
259  * be reduced to its base type to find an "exact" match.
260  */
261 static Oid
262 binary_oper_exact(List *opname, Oid arg1, Oid arg2)
263 {
264  Oid result;
265  bool was_unknown = false;
266 
267  /* Unspecified type for one of the arguments? then use the other */
268  if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
269  {
270  arg1 = arg2;
271  was_unknown = true;
272  }
273  else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
274  {
275  arg2 = arg1;
276  was_unknown = true;
277  }
278 
279  result = OpernameGetOprid(opname, arg1, arg2);
280  if (OidIsValid(result))
281  return result;
282 
283  if (was_unknown)
284  {
285  /* arg1 and arg2 are the same here, need only look at arg1 */
286  Oid basetype = getBaseType(arg1);
287 
288  if (basetype != arg1)
289  {
290  result = OpernameGetOprid(opname, basetype, basetype);
291  if (OidIsValid(result))
292  return result;
293  }
294  }
295 
296  return InvalidOid;
297 }
298 
299 
300 /* oper_select_candidate()
301  * Given the input argtype array and one or more candidates
302  * for the operator, attempt to resolve the conflict.
303  *
304  * Returns FUNCDETAIL_NOTFOUND, FUNCDETAIL_MULTIPLE, or FUNCDETAIL_NORMAL.
305  * In the success case the Oid of the best candidate is stored in *operOid.
306  *
307  * Note that the caller has already determined that there is no candidate
308  * exactly matching the input argtype(s). Incompatible candidates are not yet
309  * pruned away, however.
310  */
311 static FuncDetailCode
313  Oid *input_typeids,
314  FuncCandidateList candidates,
315  Oid *operOid) /* output argument */
316 {
317  int ncandidates;
318 
319  /*
320  * Delete any candidates that cannot actually accept the given input
321  * types, whether directly or by coercion.
322  */
323  ncandidates = func_match_argtypes(nargs, input_typeids,
324  candidates, &candidates);
325 
326  /* Done if no candidate or only one candidate survives */
327  if (ncandidates == 0)
328  {
329  *operOid = InvalidOid;
330  return FUNCDETAIL_NOTFOUND;
331  }
332  if (ncandidates == 1)
333  {
334  *operOid = candidates->oid;
335  return FUNCDETAIL_NORMAL;
336  }
337 
338  /*
339  * Use the same heuristics as for ambiguous functions to resolve the
340  * conflict.
341  */
342  candidates = func_select_candidate(nargs, input_typeids, candidates);
343 
344  if (candidates)
345  {
346  *operOid = candidates->oid;
347  return FUNCDETAIL_NORMAL;
348  }
349 
350  *operOid = InvalidOid;
351  return FUNCDETAIL_MULTIPLE; /* failed to select a best candidate */
352 }
353 
354 
355 /* oper() -- search for a binary operator
356  * Given operator name, types of arg1 and arg2, return oper struct.
357  *
358  * IMPORTANT: the returned operator (if any) is only promised to be
359  * coercion-compatible with the input datatypes. Do not use this if
360  * you need an exact- or binary-compatible match; see compatible_oper.
361  *
362  * If no matching operator found, return NULL if noError is true,
363  * raise an error if it is false. pstate and location are used only to report
364  * the error position; pass NULL/-1 if not available.
365  *
366  * NOTE: on success, the returned object is a syscache entry. The caller
367  * must ReleaseSysCache() the entry when done with it.
368  */
369 Operator
370 oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId,
371  bool noError, int location)
372 {
373  Oid operOid;
375  bool key_ok;
377  HeapTuple tup = NULL;
378 
379  /*
380  * Try to find the mapping in the lookaside cache.
381  */
382  key_ok = make_oper_cache_key(pstate, &key, opname, ltypeId, rtypeId, location);
383 
384  if (key_ok)
385  {
386  operOid = find_oper_cache_entry(&key);
387  if (OidIsValid(operOid))
388  {
389  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
390  if (HeapTupleIsValid(tup))
391  return (Operator) tup;
392  }
393  }
394 
395  /*
396  * First try for an "exact" match.
397  */
398  operOid = binary_oper_exact(opname, ltypeId, rtypeId);
399  if (!OidIsValid(operOid))
400  {
401  /*
402  * Otherwise, search for the most suitable candidate.
403  */
404  FuncCandidateList clist;
405 
406  /* Get binary operators of given name */
407  clist = OpernameGetCandidates(opname, 'b', false);
408 
409  /* No operators found? Then fail... */
410  if (clist != NULL)
411  {
412  /*
413  * Unspecified type for one of the arguments? then use the other
414  * (XXX this is probably dead code?)
415  */
416  Oid inputOids[2];
417 
418  if (rtypeId == InvalidOid)
419  rtypeId = ltypeId;
420  else if (ltypeId == InvalidOid)
421  ltypeId = rtypeId;
422  inputOids[0] = ltypeId;
423  inputOids[1] = rtypeId;
424  fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
425  }
426  }
427 
428  if (OidIsValid(operOid))
429  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
430 
431  if (HeapTupleIsValid(tup))
432  {
433  if (key_ok)
434  make_oper_cache_entry(&key, operOid);
435  }
436  else if (!noError)
437  op_error(pstate, opname, ltypeId, rtypeId, fdresult, location);
438 
439  return (Operator) tup;
440 }
441 
442 /* compatible_oper()
443  * given an opname and input datatypes, find a compatible binary operator
444  *
445  * This is tighter than oper() because it will not return an operator that
446  * requires coercion of the input datatypes (but binary-compatible operators
447  * are accepted). Otherwise, the semantics are the same.
448  */
449 Operator
450 compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2,
451  bool noError, int location)
452 {
453  Operator optup;
454  Form_pg_operator opform;
455 
456  /* oper() will find the best available match */
457  optup = oper(pstate, op, arg1, arg2, noError, location);
458  if (optup == (Operator) NULL)
459  return (Operator) NULL; /* must be noError case */
460 
461  /* but is it good enough? */
462  opform = (Form_pg_operator) GETSTRUCT(optup);
463  if (IsBinaryCoercible(arg1, opform->oprleft) &&
464  IsBinaryCoercible(arg2, opform->oprright))
465  return optup;
466 
467  /* nope... */
468  ReleaseSysCache(optup);
469 
470  if (!noError)
471  ereport(ERROR,
472  (errcode(ERRCODE_UNDEFINED_FUNCTION),
473  errmsg("operator requires run-time type coercion: %s",
474  op_signature_string(op, arg1, arg2)),
475  parser_errposition(pstate, location)));
476 
477  return (Operator) NULL;
478 }
479 
480 /* compatible_oper_opid() -- get OID of a binary operator
481  *
482  * This is a convenience routine that extracts only the operator OID
483  * from the result of compatible_oper(). InvalidOid is returned if the
484  * lookup fails and noError is true.
485  */
486 Oid
487 compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
488 {
489  Operator optup;
490  Oid result;
491 
492  optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
493  if (optup != NULL)
494  {
495  result = oprid(optup);
496  ReleaseSysCache(optup);
497  return result;
498  }
499  return InvalidOid;
500 }
501 
502 
503 /* left_oper() -- search for a unary left operator (prefix operator)
504  * Given operator name and type of arg, return oper struct.
505  *
506  * IMPORTANT: the returned operator (if any) is only promised to be
507  * coercion-compatible with the input datatype. Do not use this if
508  * you need an exact- or binary-compatible match.
509  *
510  * If no matching operator found, return NULL if noError is true,
511  * raise an error if it is false. pstate and location are used only to report
512  * the error position; pass NULL/-1 if not available.
513  *
514  * NOTE: on success, the returned object is a syscache entry. The caller
515  * must ReleaseSysCache() the entry when done with it.
516  */
517 Operator
518 left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
519 {
520  Oid operOid;
522  bool key_ok;
524  HeapTuple tup = NULL;
525 
526  /*
527  * Try to find the mapping in the lookaside cache.
528  */
529  key_ok = make_oper_cache_key(pstate, &key, op, InvalidOid, arg, location);
530 
531  if (key_ok)
532  {
533  operOid = find_oper_cache_entry(&key);
534  if (OidIsValid(operOid))
535  {
536  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
537  if (HeapTupleIsValid(tup))
538  return (Operator) tup;
539  }
540  }
541 
542  /*
543  * First try for an "exact" match.
544  */
545  operOid = OpernameGetOprid(op, InvalidOid, arg);
546  if (!OidIsValid(operOid))
547  {
548  /*
549  * Otherwise, search for the most suitable candidate.
550  */
551  FuncCandidateList clist;
552 
553  /* Get prefix operators of given name */
554  clist = OpernameGetCandidates(op, 'l', false);
555 
556  /* No operators found? Then fail... */
557  if (clist != NULL)
558  {
559  /*
560  * The returned list has args in the form (0, oprright). Move the
561  * useful data into args[0] to keep oper_select_candidate simple.
562  * XXX we are assuming here that we may scribble on the list!
563  */
564  FuncCandidateList clisti;
565 
566  for (clisti = clist; clisti != NULL; clisti = clisti->next)
567  {
568  clisti->args[0] = clisti->args[1];
569  }
570 
571  /*
572  * We must run oper_select_candidate even if only one candidate,
573  * otherwise we may falsely return a non-type-compatible operator.
574  */
575  fdresult = oper_select_candidate(1, &arg, clist, &operOid);
576  }
577  }
578 
579  if (OidIsValid(operOid))
580  tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
581 
582  if (HeapTupleIsValid(tup))
583  {
584  if (key_ok)
585  make_oper_cache_entry(&key, operOid);
586  }
587  else if (!noError)
588  op_error(pstate, op, InvalidOid, arg, fdresult, location);
589 
590  return (Operator) tup;
591 }
592 
593 /*
594  * op_signature_string
595  * Build a string representing an operator name, including arg type(s).
596  * The result is something like "integer + integer".
597  *
598  * This is typically used in the construction of operator-not-found error
599  * messages.
600  */
601 const char *
602 op_signature_string(List *op, Oid arg1, Oid arg2)
603 {
604  StringInfoData argbuf;
605 
606  initStringInfo(&argbuf);
607 
608  if (OidIsValid(arg1))
609  appendStringInfo(&argbuf, "%s ", format_type_be(arg1));
610 
612 
613  appendStringInfo(&argbuf, " %s", format_type_be(arg2));
614 
615  return argbuf.data; /* return palloc'd string buffer */
616 }
617 
618 /*
619  * op_error - utility routine to complain about an unresolvable operator
620  */
621 static void
622 op_error(ParseState *pstate, List *op,
623  Oid arg1, Oid arg2,
624  FuncDetailCode fdresult, int location)
625 {
626  if (fdresult == FUNCDETAIL_MULTIPLE)
627  ereport(ERROR,
628  (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
629  errmsg("operator is not unique: %s",
630  op_signature_string(op, arg1, arg2)),
631  errhint("Could not choose a best candidate operator. "
632  "You might need to add explicit type casts."),
633  parser_errposition(pstate, location)));
634  else
635  ereport(ERROR,
636  (errcode(ERRCODE_UNDEFINED_FUNCTION),
637  errmsg("operator does not exist: %s",
638  op_signature_string(op, arg1, arg2)),
639  (!arg1 || !arg2) ?
640  errhint("No operator matches the given name and argument type. "
641  "You might need to add an explicit type cast.") :
642  errhint("No operator matches the given name and argument types. "
643  "You might need to add explicit type casts."),
644  parser_errposition(pstate, location)));
645 }
646 
647 /*
648  * make_op()
649  * Operator expression construction.
650  *
651  * Transform operator expression ensuring type compatibility.
652  * This is where some type conversion happens.
653  *
654  * last_srf should be a copy of pstate->p_last_srf from just before we
655  * started transforming the operator's arguments; this is used for nested-SRF
656  * detection. If the caller will throw an error anyway for a set-returning
657  * expression, it's okay to cheat and just pass pstate->p_last_srf.
658  */
659 Expr *
660 make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
661  Node *last_srf, int location)
662 {
663  Oid ltypeId,
664  rtypeId;
665  Operator tup;
666  Form_pg_operator opform;
667  Oid actual_arg_types[2];
668  Oid declared_arg_types[2];
669  int nargs;
670  List *args;
671  Oid rettype;
672  OpExpr *result;
673 
674  /* Check it's not a postfix operator */
675  if (rtree == NULL)
676  ereport(ERROR,
677  (errcode(ERRCODE_SYNTAX_ERROR),
678  errmsg("postfix operators are not supported")));
679 
680  /* Select the operator */
681  if (ltree == NULL)
682  {
683  /* prefix operator */
684  rtypeId = exprType(rtree);
685  ltypeId = InvalidOid;
686  tup = left_oper(pstate, opname, rtypeId, false, location);
687  }
688  else
689  {
690  /* otherwise, binary operator */
691  ltypeId = exprType(ltree);
692  rtypeId = exprType(rtree);
693  tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
694  }
695 
696  opform = (Form_pg_operator) GETSTRUCT(tup);
697 
698  /* Check it's not a shell */
699  if (!RegProcedureIsValid(opform->oprcode))
700  ereport(ERROR,
701  (errcode(ERRCODE_UNDEFINED_FUNCTION),
702  errmsg("operator is only a shell: %s",
703  op_signature_string(opname,
704  opform->oprleft,
705  opform->oprright)),
706  parser_errposition(pstate, location)));
707 
708  /* Do typecasting and build the expression tree */
709  if (ltree == NULL)
710  {
711  /* prefix operator */
712  args = list_make1(rtree);
713  actual_arg_types[0] = rtypeId;
714  declared_arg_types[0] = opform->oprright;
715  nargs = 1;
716  }
717  else
718  {
719  /* otherwise, binary operator */
720  args = list_make2(ltree, rtree);
721  actual_arg_types[0] = ltypeId;
722  actual_arg_types[1] = rtypeId;
723  declared_arg_types[0] = opform->oprleft;
724  declared_arg_types[1] = opform->oprright;
725  nargs = 2;
726  }
727 
728  /*
729  * enforce consistency with polymorphic argument and return types,
730  * possibly adjusting return type or declared_arg_types (which will be
731  * used as the cast destination by make_fn_arguments)
732  */
733  rettype = enforce_generic_type_consistency(actual_arg_types,
734  declared_arg_types,
735  nargs,
736  opform->oprresult,
737  false);
738 
739  /* perform the necessary typecasting of arguments */
740  make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
741 
742  /* and build the expression node */
743  result = makeNode(OpExpr);
744  result->opno = oprid(tup);
745  result->opfuncid = opform->oprcode;
746  result->opresulttype = rettype;
747  result->opretset = get_func_retset(opform->oprcode);
748  /* opcollid and inputcollid will be set by parse_collate.c */
749  result->args = args;
750  result->location = location;
751 
752  /* if it returns a set, check that's OK */
753  if (result->opretset)
754  {
755  check_srf_call_placement(pstate, last_srf, location);
756  /* ... and remember it for error checks at higher levels */
757  pstate->p_last_srf = (Node *) result;
758  }
759 
760  ReleaseSysCache(tup);
761 
762  return (Expr *) result;
763 }
764 
765 /*
766  * make_scalar_array_op()
767  * Build expression tree for "scalar op ANY/ALL (array)" construct.
768  */
769 Expr *
771  bool useOr,
772  Node *ltree, Node *rtree,
773  int location)
774 {
775  Oid ltypeId,
776  rtypeId,
777  atypeId,
778  res_atypeId;
779  Operator tup;
780  Form_pg_operator opform;
781  Oid actual_arg_types[2];
782  Oid declared_arg_types[2];
783  List *args;
784  Oid rettype;
785  ScalarArrayOpExpr *result;
786 
787  ltypeId = exprType(ltree);
788  atypeId = exprType(rtree);
789 
790  /*
791  * The right-hand input of the operator will be the element type of the
792  * array. However, if we currently have just an untyped literal on the
793  * right, stay with that and hope we can resolve the operator.
794  */
795  if (atypeId == UNKNOWNOID)
796  rtypeId = UNKNOWNOID;
797  else
798  {
799  rtypeId = get_base_element_type(atypeId);
800  if (!OidIsValid(rtypeId))
801  ereport(ERROR,
802  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
803  errmsg("op ANY/ALL (array) requires array on right side"),
804  parser_errposition(pstate, location)));
805  }
806 
807  /* Now resolve the operator */
808  tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
809  opform = (Form_pg_operator) GETSTRUCT(tup);
810 
811  /* Check it's not a shell */
812  if (!RegProcedureIsValid(opform->oprcode))
813  ereport(ERROR,
814  (errcode(ERRCODE_UNDEFINED_FUNCTION),
815  errmsg("operator is only a shell: %s",
816  op_signature_string(opname,
817  opform->oprleft,
818  opform->oprright)),
819  parser_errposition(pstate, location)));
820 
821  args = list_make2(ltree, rtree);
822  actual_arg_types[0] = ltypeId;
823  actual_arg_types[1] = rtypeId;
824  declared_arg_types[0] = opform->oprleft;
825  declared_arg_types[1] = opform->oprright;
826 
827  /*
828  * enforce consistency with polymorphic argument and return types,
829  * possibly adjusting return type or declared_arg_types (which will be
830  * used as the cast destination by make_fn_arguments)
831  */
832  rettype = enforce_generic_type_consistency(actual_arg_types,
833  declared_arg_types,
834  2,
835  opform->oprresult,
836  false);
837 
838  /*
839  * Check that operator result is boolean
840  */
841  if (rettype != BOOLOID)
842  ereport(ERROR,
843  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
844  errmsg("op ANY/ALL (array) requires operator to yield boolean"),
845  parser_errposition(pstate, location)));
846  if (get_func_retset(opform->oprcode))
847  ereport(ERROR,
848  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
849  errmsg("op ANY/ALL (array) requires operator not to return a set"),
850  parser_errposition(pstate, location)));
851 
852  /*
853  * Now switch back to the array type on the right, arranging for any
854  * needed cast to be applied. Beware of polymorphic operators here;
855  * enforce_generic_type_consistency may or may not have replaced a
856  * polymorphic type with a real one.
857  */
858  if (IsPolymorphicType(declared_arg_types[1]))
859  {
860  /* assume the actual array type is OK */
861  res_atypeId = atypeId;
862  }
863  else
864  {
865  res_atypeId = get_array_type(declared_arg_types[1]);
866  if (!OidIsValid(res_atypeId))
867  ereport(ERROR,
868  (errcode(ERRCODE_UNDEFINED_OBJECT),
869  errmsg("could not find array type for data type %s",
870  format_type_be(declared_arg_types[1])),
871  parser_errposition(pstate, location)));
872  }
873  actual_arg_types[1] = atypeId;
874  declared_arg_types[1] = res_atypeId;
875 
876  /* perform the necessary typecasting of arguments */
877  make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
878 
879  /* and build the expression node */
880  result = makeNode(ScalarArrayOpExpr);
881  result->opno = oprid(tup);
882  result->opfuncid = opform->oprcode;
883  result->hashfuncid = InvalidOid;
884  result->negfuncid = InvalidOid;
885  result->useOr = useOr;
886  /* inputcollid will be set by parse_collate.c */
887  result->args = args;
888  result->location = location;
889 
890  ReleaseSysCache(tup);
891 
892  return (Expr *) result;
893 }
894 
895 
896 /*
897  * Lookaside cache to speed operator lookup. Possibly this should be in
898  * a separate module under utils/cache/ ?
899  *
900  * The idea here is that the mapping from operator name and given argument
901  * types is constant for a given search path (or single specified schema OID)
902  * so long as the contents of pg_operator and pg_cast don't change. And that
903  * mapping is pretty expensive to compute, especially for ambiguous operators;
904  * this is mainly because there are a *lot* of instances of popular operator
905  * names such as "=", and we have to check each one to see which is the
906  * best match. So once we have identified the correct mapping, we save it
907  * in a cache that need only be flushed on pg_operator or pg_cast change.
908  * (pg_cast must be considered because changes in the set of implicit casts
909  * affect the set of applicable operators for any given input datatype.)
910  *
911  * XXX in principle, ALTER TABLE ... INHERIT could affect the mapping as
912  * well, but we disregard that since there's no convenient way to find out
913  * about it, and it seems a pretty far-fetched corner-case anyway.
914  *
915  * Note: at some point it might be worth doing a similar cache for function
916  * lookups. However, the potential gain is a lot less since (a) function
917  * names are generally not overloaded as heavily as operator names, and
918  * (b) we'd have to flush on pg_proc updates, which are probably a good
919  * deal more common than pg_operator updates.
920  */
921 
922 /* The operator cache hashtable */
923 static HTAB *OprCacheHash = NULL;
924 
925 
926 /*
927  * make_oper_cache_key
928  * Fill the lookup key struct given operator name and arg types.
929  *
930  * Returns true if successful, false if the search_path overflowed
931  * (hence no caching is possible).
932  *
933  * pstate/location are used only to report the error position; pass NULL/-1
934  * if not available.
935  */
936 static bool
938  Oid ltypeId, Oid rtypeId, int location)
939 {
940  char *schemaname;
941  char *opername;
942 
943  /* deconstruct the name list */
944  DeconstructQualifiedName(opname, &schemaname, &opername);
945 
946  /* ensure zero-fill for stable hashing */
947  MemSet(key, 0, sizeof(OprCacheKey));
948 
949  /* save operator name and input types into key */
950  strlcpy(key->oprname, opername, NAMEDATALEN);
951  key->left_arg = ltypeId;
952  key->right_arg = rtypeId;
953 
954  if (schemaname)
955  {
956  ParseCallbackState pcbstate;
957 
958  /* search only in exact schema given */
959  setup_parser_errposition_callback(&pcbstate, pstate, location);
960  key->search_path[0] = LookupExplicitNamespace(schemaname, false);
962  }
963  else
964  {
965  /* get the active search path */
966  if (fetch_search_path_array(key->search_path,
968  return false; /* oops, didn't fit */
969  }
970 
971  return true;
972 }
973 
974 /*
975  * find_oper_cache_entry
976  *
977  * Look for a cache entry matching the given key. If found, return the
978  * contained operator OID, else return InvalidOid.
979  */
980 static Oid
982 {
983  OprCacheEntry *oprentry;
984 
985  if (OprCacheHash == NULL)
986  {
987  /* First time through: initialize the hash table */
988  HASHCTL ctl;
989 
990  ctl.keysize = sizeof(OprCacheKey);
991  ctl.entrysize = sizeof(OprCacheEntry);
992  OprCacheHash = hash_create("Operator lookup cache", 256,
993  &ctl, HASH_ELEM | HASH_BLOBS);
994 
995  /* Arrange to flush cache on pg_operator and pg_cast changes */
996  CacheRegisterSyscacheCallback(OPERNAMENSP,
998  (Datum) 0);
999  CacheRegisterSyscacheCallback(CASTSOURCETARGET,
1001  (Datum) 0);
1002  }
1003 
1004  /* Look for an existing entry */
1005  oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1006  key,
1007  HASH_FIND, NULL);
1008  if (oprentry == NULL)
1009  return InvalidOid;
1010 
1011  return oprentry->opr_oid;
1012 }
1013 
1014 /*
1015  * make_oper_cache_entry
1016  *
1017  * Insert a cache entry for the given key.
1018  */
1019 static void
1021 {
1022  OprCacheEntry *oprentry;
1023 
1024  Assert(OprCacheHash != NULL);
1025 
1026  oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1027  key,
1028  HASH_ENTER, NULL);
1029  oprentry->opr_oid = opr_oid;
1030 }
1031 
1032 /*
1033  * Callback for pg_operator and pg_cast inval events
1034  */
1035 static void
1036 InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
1037 {
1038  HASH_SEQ_STATUS status;
1039  OprCacheEntry *hentry;
1040 
1041  Assert(OprCacheHash != NULL);
1042 
1043  /* Currently we just flush all entries; hard to be smarter ... */
1044  hash_seq_init(&status, OprCacheHash);
1045 
1046  while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
1047  {
1049  &hentry->key,
1050  HASH_REMOVE, NULL) == NULL)
1051  elog(ERROR, "hash table corrupted");
1052  }
1053 }
unsigned int uint32
Definition: c.h:506
#define RegProcedureIsValid(p)
Definition: c.h:777
#define Assert(condition)
Definition: c.h:858
#define MemSet(start, val, len)
Definition: c.h:1020
#define OidIsValid(objectId)
Definition: c.h:775
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1395
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1385
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:857
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
@ HASH_FIND
Definition: hsearch.h:113
@ HASH_REMOVE
Definition: hsearch.h:115
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1516
bool get_func_retset(Oid funcid)
Definition: lsyscache.c:1742
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2832
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2521
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2787
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1770
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3370
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:3286
char * NameListToString(const List *names)
Definition: namespace.c:3579
FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
Definition: namespace.c:1873
int fetch_search_path_array(Oid *sarray, int sarray_len)
Definition: namespace.c:4835
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define makeNode(_type_)
Definition: nodes.h:155
Oid enforce_generic_type_consistency(const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, bool allow_poly)
bool IsBinaryCoercible(Oid srctype, Oid targettype)
void make_fn_arguments(ParseState *pstate, List *fargs, Oid *actual_arg_types, Oid *declared_arg_types)
Definition: parse_func.c:1825
FuncCandidateList func_select_candidate(int nargs, Oid *input_typeids, FuncCandidateList candidates)
Definition: parse_func.c:1008
void check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
Definition: parse_func.c:2511
int func_match_argtypes(int nargs, Oid *input_typeids, FuncCandidateList raw_candidates, FuncCandidateList *candidates)
Definition: parse_func.c:923
FuncDetailCode
Definition: parse_func.h:23
@ FUNCDETAIL_MULTIPLE
Definition: parse_func.h:25
@ FUNCDETAIL_NORMAL
Definition: parse_func.h:26
@ FUNCDETAIL_NOTFOUND
Definition: parse_func.h:24
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:156
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:140
static void InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
Definition: parse_oper.c:1036
static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
Definition: parse_oper.c:1020
static FuncDetailCode oper_select_candidate(int nargs, Oid *input_typeids, FuncCandidateList candidates, Oid *operOid)
Definition: parse_oper.c:312
Operator left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
Definition: parse_oper.c:518
void get_sort_group_operators(Oid argtype, bool needLT, bool needEQ, bool needGT, Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, bool *isHashable)
Definition: parse_oper.c:180
#define MAX_CACHED_PATH_LEN
Definition: parse_oper.c:49
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, Node *last_srf, int location)
Definition: parse_oper.c:660
Oid LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright, bool noError, int location)
Definition: parse_oper.c:99
Oid oprfuncid(Operator op)
Definition: parse_oper.c:245
static bool make_oper_cache_key(ParseState *pstate, OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId, int location)
Definition: parse_oper.c:937
static HTAB * OprCacheHash
Definition: parse_oper.c:923
Oid oprid(Operator op)
Definition: parse_oper.c:238
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:370
struct OprCacheEntry OprCacheEntry
const char * op_signature_string(List *op, Oid arg1, Oid arg2)
Definition: parse_oper.c:602
static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2)
Definition: parse_oper.c:262
static void op_error(ParseState *pstate, List *op, Oid arg1, Oid arg2, FuncDetailCode fdresult, int location)
Definition: parse_oper.c:622
static Oid find_oper_cache_entry(OprCacheKey *key)
Definition: parse_oper.c:981
Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:770
Oid compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
Definition: parse_oper.c:487
Operator compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2, bool noError, int location)
Definition: parse_oper.c:450
Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError)
Definition: parse_oper.c:133
struct OprCacheKey OprCacheKey
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
Definition: parse_type.c:232
void * arg
#define NAMEDATALEN
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial_node(type, l)
Definition: pg_list.h:181
#define lsecond_node(type, l)
Definition: pg_list.h:186
#define list_make1(x1)
Definition: pg_list.h:212
#define list_make2(x1, x2)
Definition: pg_list.h:214
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
uintptr_t Datum
Definition: postgres.h:64
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
tree ctl
Definition: radixtree.h:1851
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Definition: dynahash.c:220
Definition: pg_list.h:54
Definition: nodes.h:129
Oid opno
Definition: primnodes.h:818
List * args
Definition: primnodes.h:836
ParseLoc location
Definition: primnodes.h:839
OprCacheKey key
Definition: parse_oper.c:62
Oid right_arg
Definition: parse_oper.c:55
Oid search_path[MAX_CACHED_PATH_LEN]
Definition: parse_oper.c:56
char oprname[NAMEDATALEN]
Definition: parse_oper.c:53
Oid left_arg
Definition: parse_oper.c:54
Node * p_last_srf
Definition: parse_node.h:229
ParseLoc location
Definition: primnodes.h:919
struct _FuncCandidateList * next
Definition: namespace.h:31
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:39
Definition: ltree.h:43
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:346
#define TYPECACHE_EQ_OPR
Definition: typcache.h:137
#define TYPECACHE_GT_OPR
Definition: typcache.h:139
#define TYPECACHE_LT_OPR
Definition: typcache.h:138
#define TYPECACHE_HASH_PROC
Definition: typcache.h:141