1 /*-------------------------------------------------------------------------
4 * handle operator things for parser
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.106 2008/09/09 18:58:08 tgl Exp $
13 *-------------------------------------------------------------------------
18 #include "catalog/pg_operator.h"
19 #include "catalog/pg_type.h"
20 #include "lib/stringinfo.h"
21 #include "nodes/nodeFuncs.h"
22 #include "parser/parse_coerce.h"
23 #include "parser/parse_func.h"
24 #include "parser/parse_oper.h"
25 #include "parser/parse_type.h"
26 #include "utils/builtins.h"
27 #include "utils/hsearch.h"
28 #include "utils/inval.h"
29 #include "utils/lsyscache.h"
30 #include "utils/syscache.h"
31 #include "utils/typcache.h"
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.
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.
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.
48 /* If your search_path is longer than this, sucks to be you ... */
49 #define MAX_CACHED_PATH_LEN 16
51 typedef struct OprCacheKey
53 char oprname[NAMEDATALEN];
54 Oid left_arg; /* Left input OID, or 0 if prefix op */
55 Oid right_arg; /* Right input OID, or 0 if postfix op */
56 Oid search_path[MAX_CACHED_PATH_LEN];
59 typedef struct OprCacheEntry
61 /* the hash lookup key MUST BE FIRST */
64 Oid opr_oid; /* OID of the resolved operator */
68 static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2);
69 static FuncDetailCode oper_select_candidate(int nargs,
71 FuncCandidateList candidates,
73 static const char *op_signature_string(List *op, char oprkind,
75 static void op_error(ParseState *pstate, List *op, char oprkind,
77 FuncDetailCode fdresult, int location);
78 static bool make_oper_cache_key(OprCacheKey *key, List *opname,
79 Oid ltypeId, Oid rtypeId);
80 static Oid find_oper_cache_entry(OprCacheKey *key);
81 static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid);
82 static void InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr);
87 * Given a possibly-qualified operator name and exact input datatypes,
88 * look up the operator.
90 * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for
93 * If the operator name is not schema-qualified, it is sought in the current
94 * namespace search path.
96 * If the operator is not found, we return InvalidOid if noError is true,
97 * else raise an error. pstate and location are used only to report the
98 * error position; pass NULL/-1 if not available.
101 LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
102 bool noError, int location)
106 result = OpernameGetOprid(opername, oprleft, oprright);
107 if (OidIsValid(result))
110 /* we don't use op_error here because only an exact match is wanted */
115 if (!OidIsValid(oprleft))
117 else if (!OidIsValid(oprright))
123 (errcode(ERRCODE_UNDEFINED_FUNCTION),
124 errmsg("operator does not exist: %s",
125 op_signature_string(opername, oprkind,
127 parser_errposition(pstate, location)));
134 * LookupOperNameTypeNames
135 * Like LookupOperName, but the argument types are specified by
138 * Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op.
141 LookupOperNameTypeNames(ParseState *pstate, List *opername,
142 TypeName *oprleft, TypeName *oprright,
143 bool noError, int location)
149 leftoid = InvalidOid;
151 leftoid = typenameTypeId(pstate, oprleft, NULL);
153 if (oprright == NULL)
154 rightoid = InvalidOid;
156 rightoid = typenameTypeId(pstate, oprright, NULL);
158 return LookupOperName(pstate, opername, leftoid, rightoid,
163 * get_sort_group_operators - get default sorting/grouping operators for type
165 * We fetch the "<", "=", and ">" operators all at once to reduce lookup
166 * overhead (knowing that most callers will be interested in at least two).
167 * However, a given datatype might have only an "=" operator, if it is
168 * hashable but not sortable. (Other combinations of present and missing
169 * operators shouldn't happen, unless the system catalogs are messed up.)
171 * If an operator is missing and the corresponding needXX flag is true,
172 * throw a standard error message, else return InvalidOid.
174 * Callers can pass NULL pointers for any results they don't care to get.
176 * Note: the results are guaranteed to be exact or binary-compatible matches,
177 * since most callers are not prepared to cope with adding any run-time type
181 get_sort_group_operators(Oid argtype,
182 bool needLT, bool needEQ, bool needGT,
183 Oid *ltOpr, Oid *eqOpr, Oid *gtOpr)
185 TypeCacheEntry *typentry;
191 * Look up the operators using the type cache.
193 * Note: the search algorithm used by typcache.c ensures that the results
194 * are consistent, ie all from the same opclass.
196 typentry = lookup_type_cache(argtype,
197 TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR);
198 lt_opr = typentry->lt_opr;
199 eq_opr = typentry->eq_opr;
200 gt_opr = typentry->gt_opr;
203 * If the datatype is an array, then we can use array_lt and friends ...
204 * but only if there are suitable operators for the element type. (This
205 * check is not in the raw typcache.c code ... should it be?) Testing
206 * all three operator IDs here should be redundant.
208 if (lt_opr == ARRAY_LT_OP ||
209 eq_opr == ARRAY_EQ_OP ||
210 gt_opr == ARRAY_GT_OP)
212 Oid elem_type = get_element_type(argtype);
214 if (OidIsValid(elem_type))
216 typentry = lookup_type_cache(elem_type,
217 TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR);
218 if (!OidIsValid(typentry->lt_opr))
219 lt_opr = InvalidOid; /* element type has no "<" */
220 if (!OidIsValid(typentry->eq_opr))
221 eq_opr = InvalidOid; /* element type has no "=" */
222 if (!OidIsValid(typentry->gt_opr))
223 gt_opr = InvalidOid; /* element type has no ">" */
226 lt_opr = eq_opr = gt_opr = InvalidOid; /* bogus array type? */
229 /* Report errors if needed */
230 if ((needLT && !OidIsValid(lt_opr)) ||
231 (needGT && !OidIsValid(gt_opr)))
233 (errcode(ERRCODE_UNDEFINED_FUNCTION),
234 errmsg("could not identify an ordering operator for type %s",
235 format_type_be(argtype)),
236 errhint("Use an explicit ordering operator or modify the query.")));
237 if (needEQ && !OidIsValid(eq_opr))
239 (errcode(ERRCODE_UNDEFINED_FUNCTION),
240 errmsg("could not identify an equality operator for type %s",
241 format_type_be(argtype))));
243 /* Return results as needed */
253 /* given operator tuple, return the operator OID */
257 return HeapTupleGetOid(op);
260 /* given operator tuple, return the underlying function's OID */
262 oprfuncid(Operator op)
264 Form_pg_operator pgopform = (Form_pg_operator) GETSTRUCT(op);
266 return pgopform->oprcode;
270 /* binary_oper_exact()
271 * Check for an "exact" match to the specified operand types.
273 * If one operand is an unknown literal, assume it should be taken to be
274 * the same type as the other operand for this purpose. Also, consider
275 * the possibility that the other operand is a domain type that needs to
276 * be reduced to its base type to find an "exact" match.
279 binary_oper_exact(List *opname, Oid arg1, Oid arg2)
282 bool was_unknown = false;
284 /* Unspecified type for one of the arguments? then use the other */
285 if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
290 else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
296 result = OpernameGetOprid(opname, arg1, arg2);
297 if (OidIsValid(result))
302 /* arg1 and arg2 are the same here, need only look at arg1 */
303 Oid basetype = getBaseType(arg1);
305 if (basetype != arg1)
307 result = OpernameGetOprid(opname, basetype, basetype);
308 if (OidIsValid(result))
317 /* oper_select_candidate()
318 * Given the input argtype array and one or more candidates
319 * for the operator, attempt to resolve the conflict.
321 * Returns FUNCDETAIL_NOTFOUND, FUNCDETAIL_MULTIPLE, or FUNCDETAIL_NORMAL.
322 * In the success case the Oid of the best candidate is stored in *operOid.
324 * Note that the caller has already determined that there is no candidate
325 * exactly matching the input argtype(s). Incompatible candidates are not yet
326 * pruned away, however.
328 static FuncDetailCode
329 oper_select_candidate(int nargs,
331 FuncCandidateList candidates,
332 Oid *operOid) /* output argument */
337 * Delete any candidates that cannot actually accept the given input
338 * types, whether directly or by coercion.
340 ncandidates = func_match_argtypes(nargs, input_typeids,
341 candidates, &candidates);
343 /* Done if no candidate or only one candidate survives */
344 if (ncandidates == 0)
346 *operOid = InvalidOid;
347 return FUNCDETAIL_NOTFOUND;
349 if (ncandidates == 1)
351 *operOid = candidates->oid;
352 return FUNCDETAIL_NORMAL;
356 * Use the same heuristics as for ambiguous functions to resolve the
359 candidates = func_select_candidate(nargs, input_typeids, candidates);
363 *operOid = candidates->oid;
364 return FUNCDETAIL_NORMAL;
367 *operOid = InvalidOid;
368 return FUNCDETAIL_MULTIPLE; /* failed to select a best candidate */
372 /* oper() -- search for a binary operator
373 * Given operator name, types of arg1 and arg2, return oper struct.
375 * IMPORTANT: the returned operator (if any) is only promised to be
376 * coercion-compatible with the input datatypes. Do not use this if
377 * you need an exact- or binary-compatible match; see compatible_oper.
379 * If no matching operator found, return NULL if noError is true,
380 * raise an error if it is false. pstate and location are used only to report
381 * the error position; pass NULL/-1 if not available.
383 * NOTE: on success, the returned object is a syscache entry. The caller
384 * must ReleaseSysCache() the entry when done with it.
387 oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId,
388 bool noError, int location)
393 FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
394 HeapTuple tup = NULL;
397 * Try to find the mapping in the lookaside cache.
399 key_ok = make_oper_cache_key(&key, opname, ltypeId, rtypeId);
402 operOid = find_oper_cache_entry(&key);
403 if (OidIsValid(operOid))
405 tup = SearchSysCache(OPEROID,
406 ObjectIdGetDatum(operOid),
408 if (HeapTupleIsValid(tup))
409 return (Operator) tup;
414 * First try for an "exact" match.
416 operOid = binary_oper_exact(opname, ltypeId, rtypeId);
417 if (!OidIsValid(operOid))
420 * Otherwise, search for the most suitable candidate.
422 FuncCandidateList clist;
424 /* Get binary operators of given name */
425 clist = OpernameGetCandidates(opname, 'b');
427 /* No operators found? Then fail... */
431 * Unspecified type for one of the arguments? then use the other
432 * (XXX this is probably dead code?)
436 if (rtypeId == InvalidOid)
438 else if (ltypeId == InvalidOid)
440 inputOids[0] = ltypeId;
441 inputOids[1] = rtypeId;
442 fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
446 if (OidIsValid(operOid))
447 tup = SearchSysCache(OPEROID,
448 ObjectIdGetDatum(operOid),
451 if (HeapTupleIsValid(tup))
454 make_oper_cache_entry(&key, operOid);
457 op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location);
459 return (Operator) tup;
463 * given an opname and input datatypes, find a compatible binary operator
465 * This is tighter than oper() because it will not return an operator that
466 * requires coercion of the input datatypes (but binary-compatible operators
467 * are accepted). Otherwise, the semantics are the same.
470 compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2,
471 bool noError, int location)
474 Form_pg_operator opform;
476 /* oper() will find the best available match */
477 optup = oper(pstate, op, arg1, arg2, noError, location);
478 if (optup == (Operator) NULL)
479 return (Operator) NULL; /* must be noError case */
481 /* but is it good enough? */
482 opform = (Form_pg_operator) GETSTRUCT(optup);
483 if (IsBinaryCoercible(arg1, opform->oprleft) &&
484 IsBinaryCoercible(arg2, opform->oprright))
488 ReleaseSysCache(optup);
492 (errcode(ERRCODE_UNDEFINED_FUNCTION),
493 errmsg("operator requires run-time type coercion: %s",
494 op_signature_string(op, 'b', arg1, arg2)),
495 parser_errposition(pstate, location)));
497 return (Operator) NULL;
500 /* compatible_oper_opid() -- get OID of a binary operator
502 * This is a convenience routine that extracts only the operator OID
503 * from the result of compatible_oper(). InvalidOid is returned if the
504 * lookup fails and noError is true.
507 compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
512 optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
515 result = oprid(optup);
516 ReleaseSysCache(optup);
523 /* right_oper() -- search for a unary right operator (postfix operator)
524 * Given operator name and type of arg, return oper struct.
526 * IMPORTANT: the returned operator (if any) is only promised to be
527 * coercion-compatible with the input datatype. Do not use this if
528 * you need an exact- or binary-compatible match.
530 * If no matching operator found, return NULL if noError is true,
531 * raise an error if it is false. pstate and location are used only to report
532 * the error position; pass NULL/-1 if not available.
534 * NOTE: on success, the returned object is a syscache entry. The caller
535 * must ReleaseSysCache() the entry when done with it.
538 right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
543 FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
544 HeapTuple tup = NULL;
547 * Try to find the mapping in the lookaside cache.
549 key_ok = make_oper_cache_key(&key, op, arg, InvalidOid);
552 operOid = find_oper_cache_entry(&key);
553 if (OidIsValid(operOid))
555 tup = SearchSysCache(OPEROID,
556 ObjectIdGetDatum(operOid),
558 if (HeapTupleIsValid(tup))
559 return (Operator) tup;
564 * First try for an "exact" match.
566 operOid = OpernameGetOprid(op, arg, InvalidOid);
567 if (!OidIsValid(operOid))
570 * Otherwise, search for the most suitable candidate.
572 FuncCandidateList clist;
574 /* Get postfix operators of given name */
575 clist = OpernameGetCandidates(op, 'r');
577 /* No operators found? Then fail... */
581 * We must run oper_select_candidate even if only one candidate,
582 * otherwise we may falsely return a non-type-compatible operator.
584 fdresult = oper_select_candidate(1, &arg, clist, &operOid);
588 if (OidIsValid(operOid))
589 tup = SearchSysCache(OPEROID,
590 ObjectIdGetDatum(operOid),
593 if (HeapTupleIsValid(tup))
596 make_oper_cache_entry(&key, operOid);
599 op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location);
601 return (Operator) tup;
605 /* left_oper() -- search for a unary left operator (prefix operator)
606 * Given operator name and type of arg, return oper struct.
608 * IMPORTANT: the returned operator (if any) is only promised to be
609 * coercion-compatible with the input datatype. Do not use this if
610 * you need an exact- or binary-compatible match.
612 * If no matching operator found, return NULL if noError is true,
613 * raise an error if it is false. pstate and location are used only to report
614 * the error position; pass NULL/-1 if not available.
616 * NOTE: on success, the returned object is a syscache entry. The caller
617 * must ReleaseSysCache() the entry when done with it.
620 left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
625 FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
626 HeapTuple tup = NULL;
629 * Try to find the mapping in the lookaside cache.
631 key_ok = make_oper_cache_key(&key, op, InvalidOid, arg);
634 operOid = find_oper_cache_entry(&key);
635 if (OidIsValid(operOid))
637 tup = SearchSysCache(OPEROID,
638 ObjectIdGetDatum(operOid),
640 if (HeapTupleIsValid(tup))
641 return (Operator) tup;
646 * First try for an "exact" match.
648 operOid = OpernameGetOprid(op, InvalidOid, arg);
649 if (!OidIsValid(operOid))
652 * Otherwise, search for the most suitable candidate.
654 FuncCandidateList clist;
656 /* Get prefix operators of given name */
657 clist = OpernameGetCandidates(op, 'l');
659 /* No operators found? Then fail... */
663 * The returned list has args in the form (0, oprright). Move the
664 * useful data into args[0] to keep oper_select_candidate simple.
665 * XXX we are assuming here that we may scribble on the list!
667 FuncCandidateList clisti;
669 for (clisti = clist; clisti != NULL; clisti = clisti->next)
671 clisti->args[0] = clisti->args[1];
675 * We must run oper_select_candidate even if only one candidate,
676 * otherwise we may falsely return a non-type-compatible operator.
678 fdresult = oper_select_candidate(1, &arg, clist, &operOid);
682 if (OidIsValid(operOid))
683 tup = SearchSysCache(OPEROID,
684 ObjectIdGetDatum(operOid),
687 if (HeapTupleIsValid(tup))
690 make_oper_cache_entry(&key, operOid);
693 op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location);
695 return (Operator) tup;
699 * op_signature_string
700 * Build a string representing an operator name, including arg type(s).
701 * The result is something like "integer + integer".
703 * This is typically used in the construction of operator-not-found error
707 op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
709 StringInfoData argbuf;
711 initStringInfo(&argbuf);
714 appendStringInfo(&argbuf, "%s ", format_type_be(arg1));
716 appendStringInfoString(&argbuf, NameListToString(op));
719 appendStringInfo(&argbuf, " %s", format_type_be(arg2));
721 return argbuf.data; /* return palloc'd string buffer */
725 * op_error - utility routine to complain about an unresolvable operator
728 op_error(ParseState *pstate, List *op, char oprkind,
730 FuncDetailCode fdresult, int location)
732 if (fdresult == FUNCDETAIL_MULTIPLE)
734 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
735 errmsg("operator is not unique: %s",
736 op_signature_string(op, oprkind, arg1, arg2)),
737 errhint("Could not choose a best candidate operator. "
738 "You might need to add explicit type casts."),
739 parser_errposition(pstate, location)));
742 (errcode(ERRCODE_UNDEFINED_FUNCTION),
743 errmsg("operator does not exist: %s",
744 op_signature_string(op, oprkind, arg1, arg2)),
745 errhint("No operator matches the given name and argument type(s). "
746 "You might need to add explicit type casts."),
747 parser_errposition(pstate, location)));
752 * Operator expression construction.
754 * Transform operator expression ensuring type compatibility.
755 * This is where some type conversion happens.
757 * As with coerce_type, pstate may be NULL if no special unknown-Param
758 * processing is wanted.
761 make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
767 Form_pg_operator opform;
768 Oid actual_arg_types[2];
769 Oid declared_arg_types[2];
775 /* Select the operator */
779 ltypeId = exprType(ltree);
780 rtypeId = InvalidOid;
781 tup = right_oper(pstate, opname, ltypeId, false, location);
783 else if (ltree == NULL)
786 rtypeId = exprType(rtree);
787 ltypeId = InvalidOid;
788 tup = left_oper(pstate, opname, rtypeId, false, location);
792 /* otherwise, binary operator */
793 ltypeId = exprType(ltree);
794 rtypeId = exprType(rtree);
795 tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
798 opform = (Form_pg_operator) GETSTRUCT(tup);
800 /* Check it's not a shell */
801 if (!RegProcedureIsValid(opform->oprcode))
803 (errcode(ERRCODE_UNDEFINED_FUNCTION),
804 errmsg("operator is only a shell: %s",
805 op_signature_string(opname,
809 parser_errposition(pstate, location)));
811 /* Do typecasting and build the expression tree */
815 args = list_make1(ltree);
816 actual_arg_types[0] = ltypeId;
817 declared_arg_types[0] = opform->oprleft;
820 else if (ltree == NULL)
823 args = list_make1(rtree);
824 actual_arg_types[0] = rtypeId;
825 declared_arg_types[0] = opform->oprright;
830 /* otherwise, binary operator */
831 args = list_make2(ltree, rtree);
832 actual_arg_types[0] = ltypeId;
833 actual_arg_types[1] = rtypeId;
834 declared_arg_types[0] = opform->oprleft;
835 declared_arg_types[1] = opform->oprright;
840 * enforce consistency with polymorphic argument and return types,
841 * possibly adjusting return type or declared_arg_types (which will be
842 * used as the cast destination by make_fn_arguments)
844 rettype = enforce_generic_type_consistency(actual_arg_types,
850 /* perform the necessary typecasting of arguments */
851 make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
853 /* and build the expression node */
854 result = makeNode(OpExpr);
855 result->opno = oprid(tup);
856 result->opfuncid = opform->oprcode;
857 result->opresulttype = rettype;
858 result->opretset = get_func_retset(opform->oprcode);
860 result->location = location;
862 ReleaseSysCache(tup);
864 return (Expr *) result;
868 * make_scalar_array_op()
869 * Build expression tree for "scalar op ANY/ALL (array)" construct.
872 make_scalar_array_op(ParseState *pstate, List *opname,
874 Node *ltree, Node *rtree,
882 Form_pg_operator opform;
883 Oid actual_arg_types[2];
884 Oid declared_arg_types[2];
887 ScalarArrayOpExpr *result;
889 ltypeId = exprType(ltree);
890 atypeId = exprType(rtree);
893 * The right-hand input of the operator will be the element type of the
894 * array. However, if we currently have just an untyped literal on the
895 * right, stay with that and hope we can resolve the operator.
897 if (atypeId == UNKNOWNOID)
898 rtypeId = UNKNOWNOID;
901 rtypeId = get_element_type(atypeId);
902 if (!OidIsValid(rtypeId))
904 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
905 errmsg("op ANY/ALL (array) requires array on right side"),
906 parser_errposition(pstate, location)));
909 /* Now resolve the operator */
910 tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
911 opform = (Form_pg_operator) GETSTRUCT(tup);
913 /* Check it's not a shell */
914 if (!RegProcedureIsValid(opform->oprcode))
916 (errcode(ERRCODE_UNDEFINED_FUNCTION),
917 errmsg("operator is only a shell: %s",
918 op_signature_string(opname,
922 parser_errposition(pstate, location)));
924 args = list_make2(ltree, rtree);
925 actual_arg_types[0] = ltypeId;
926 actual_arg_types[1] = rtypeId;
927 declared_arg_types[0] = opform->oprleft;
928 declared_arg_types[1] = opform->oprright;
931 * enforce consistency with polymorphic argument and return types,
932 * possibly adjusting return type or declared_arg_types (which will be
933 * used as the cast destination by make_fn_arguments)
935 rettype = enforce_generic_type_consistency(actual_arg_types,
942 * Check that operator result is boolean
944 if (rettype != BOOLOID)
946 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
947 errmsg("op ANY/ALL (array) requires operator to yield boolean"),
948 parser_errposition(pstate, location)));
949 if (get_func_retset(opform->oprcode))
951 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
952 errmsg("op ANY/ALL (array) requires operator not to return a set"),
953 parser_errposition(pstate, location)));
956 * Now switch back to the array type on the right, arranging for any
957 * needed cast to be applied. Beware of polymorphic operators here;
958 * enforce_generic_type_consistency may or may not have replaced a
959 * polymorphic type with a real one.
961 if (IsPolymorphicType(declared_arg_types[1]))
963 /* assume the actual array type is OK */
964 res_atypeId = atypeId;
968 res_atypeId = get_array_type(declared_arg_types[1]);
969 if (!OidIsValid(res_atypeId))
971 (errcode(ERRCODE_UNDEFINED_OBJECT),
972 errmsg("could not find array type for data type %s",
973 format_type_be(declared_arg_types[1])),
974 parser_errposition(pstate, location)));
976 actual_arg_types[1] = atypeId;
977 declared_arg_types[1] = res_atypeId;
979 /* perform the necessary typecasting of arguments */
980 make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
982 /* and build the expression node */
983 result = makeNode(ScalarArrayOpExpr);
984 result->opno = oprid(tup);
985 result->opfuncid = opform->oprcode;
986 result->useOr = useOr;
988 result->location = location;
990 ReleaseSysCache(tup);
992 return (Expr *) result;
997 * Lookaside cache to speed operator lookup. Possibly this should be in
998 * a separate module under utils/cache/ ?
1000 * The idea here is that the mapping from operator name and given argument
1001 * types is constant for a given search path (or single specified schema OID)
1002 * so long as the contents of pg_operator and pg_cast don't change. And that
1003 * mapping is pretty expensive to compute, especially for ambiguous operators;
1004 * this is mainly because there are a *lot* of instances of popular operator
1005 * names such as "=", and we have to check each one to see which is the
1006 * best match. So once we have identified the correct mapping, we save it
1007 * in a cache that need only be flushed on pg_operator or pg_cast change.
1008 * (pg_cast must be considered because changes in the set of implicit casts
1009 * affect the set of applicable operators for any given input datatype.)
1011 * XXX in principle, ALTER TABLE ... INHERIT could affect the mapping as
1012 * well, but we disregard that since there's no convenient way to find out
1013 * about it, and it seems a pretty far-fetched corner-case anyway.
1015 * Note: at some point it might be worth doing a similar cache for function
1016 * lookups. However, the potential gain is a lot less since (a) function
1017 * names are generally not overloaded as heavily as operator names, and
1018 * (b) we'd have to flush on pg_proc updates, which are probably a good
1019 * deal more common than pg_operator updates.
1022 /* The operator cache hashtable */
1023 static HTAB *OprCacheHash = NULL;
1027 * make_oper_cache_key
1028 * Fill the lookup key struct given operator name and arg types.
1030 * Returns TRUE if successful, FALSE if the search_path overflowed
1031 * (hence no caching is possible).
1034 make_oper_cache_key(OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId)
1039 /* deconstruct the name list */
1040 DeconstructQualifiedName(opname, &schemaname, &opername);
1042 /* ensure zero-fill for stable hashing */
1043 MemSet(key, 0, sizeof(OprCacheKey));
1045 /* save operator name and input types into key */
1046 strlcpy(key->oprname, opername, NAMEDATALEN);
1047 key->left_arg = ltypeId;
1048 key->right_arg = rtypeId;
1052 /* search only in exact schema given */
1053 key->search_path[0] = LookupExplicitNamespace(schemaname);
1057 /* get the active search path */
1058 if (fetch_search_path_array(key->search_path,
1059 MAX_CACHED_PATH_LEN) > MAX_CACHED_PATH_LEN)
1060 return false; /* oops, didn't fit */
1067 * find_oper_cache_entry
1069 * Look for a cache entry matching the given key. If found, return the
1070 * contained operator OID, else return InvalidOid.
1073 find_oper_cache_entry(OprCacheKey *key)
1075 OprCacheEntry *oprentry;
1077 if (OprCacheHash == NULL)
1079 /* First time through: initialize the hash table */
1082 if (!CacheMemoryContext)
1083 CreateCacheMemoryContext();
1085 MemSet(&ctl, 0, sizeof(ctl));
1086 ctl.keysize = sizeof(OprCacheKey);
1087 ctl.entrysize = sizeof(OprCacheEntry);
1088 ctl.hash = tag_hash;
1089 OprCacheHash = hash_create("Operator lookup cache", 256,
1090 &ctl, HASH_ELEM | HASH_FUNCTION);
1092 /* Arrange to flush cache on pg_operator and pg_cast changes */
1093 CacheRegisterSyscacheCallback(OPERNAMENSP,
1094 InvalidateOprCacheCallBack,
1096 CacheRegisterSyscacheCallback(CASTSOURCETARGET,
1097 InvalidateOprCacheCallBack,
1101 /* Look for an existing entry */
1102 oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1105 if (oprentry == NULL)
1108 return oprentry->opr_oid;
1112 * make_oper_cache_entry
1114 * Insert a cache entry for the given key.
1117 make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
1119 OprCacheEntry *oprentry;
1121 Assert(OprCacheHash != NULL);
1123 oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1126 oprentry->opr_oid = opr_oid;
1130 * Callback for pg_operator and pg_cast inval events
1133 InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr)
1135 HASH_SEQ_STATUS status;
1136 OprCacheEntry *hentry;
1138 Assert(OprCacheHash != NULL);
1140 /* Currently we just flush all entries; hard to be smarter ... */
1141 hash_seq_init(&status, OprCacheHash);
1143 while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
1145 if (hash_search(OprCacheHash,
1146 (void *) &hentry->key,
1147 HASH_REMOVE, NULL) == NULL)
1148 elog(ERROR, "hash table corrupted");