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-2025, 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
51typedef struct OprCacheKey
52{
54 Oid left_arg; /* Left input OID, or 0 if prefix op */
55 Oid right_arg; /* Right input OID */
58
59typedef struct OprCacheEntry
60{
61 /* the hash lookup key MUST BE FIRST */
63
64 Oid opr_oid; /* OID of the resolved operator */
66
67
68static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2);
70 Oid *input_typeids,
71 FuncCandidateList candidates,
72 Oid *operOid);
73static void op_error(ParseState *pstate, List *op,
74 Oid arg1, Oid arg2,
75 FuncDetailCode fdresult, int location);
76static bool make_oper_cache_key(ParseState *pstate, OprCacheKey *key,
77 List *opname, Oid ltypeId, Oid rtypeId,
78 int location);
80static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid);
81static 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 */
98Oid
99LookupOperName(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))
113 (errcode(ERRCODE_SYNTAX_ERROR),
114 errmsg("postfix operators are not supported"),
115 parser_errposition(pstate, location)));
116
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 */
132Oid
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 */
179void
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)))
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))
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 */
237Oid
239{
240 return ((Form_pg_operator) GETSTRUCT(op))->oid;
241}
242
243/* given operator tuple, return the underlying function's OID */
244Oid
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 */
261static Oid
262binary_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 */
311static 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 */
370oper(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 */
450compatible_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)
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 */
486Oid
487compatible_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 */
518left_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 */
601const char *
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 */
621static void
623 Oid arg1, Oid arg2,
624 FuncDetailCode fdresult, int location)
625{
626 if (fdresult == FUNCDETAIL_MULTIPLE)
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
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 */
659Expr *
660make_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)
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))
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 */
769Expr *
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))
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))
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)
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))
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))
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 */
923static 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 */
936static 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 */
980static 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,
994
995 /* Arrange to flush cache on pg_operator and pg_cast changes */
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 */
1019static 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 */
1035static void
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}
#define RegProcedureIsValid(p)
Definition: c.h:734
#define Assert(condition)
Definition: c.h:815
uint32_t uint32
Definition: c.h:488
#define MemSet(start, val, len)
Definition: c.h:977
#define OidIsValid(objectId)
Definition: c.h:732
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1420
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
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:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#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:1704
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:1785
char * NameListToString(const List *names)
Definition: namespace.c:3594
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3385
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:3301
FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
Definition: namespace.c:1888
int fetch_search_path_array(Oid *sarray, int sarray_len)
Definition: namespace.c:4859
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
Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:770
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
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
const char * op_signature_string(List *op, Oid arg1, Oid arg2)
Definition: parse_oper.c:602
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:69
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
tree ctl
Definition: radixtree.h:1838
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
Definition: dynahash.c:220
Definition: pg_list.h:54
Definition: nodes.h:129
Oid opno
Definition: primnodes.h:834
List * args
Definition: primnodes.h:852
ParseLoc location
Definition: primnodes.h:855
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:248
ParseLoc location
Definition: primnodes.h:935
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:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:386
#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