1
/*-------------------------------------------------------------------------
4
* handle operator things for parser
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/backend/parser/parse_oper.c
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);
153
if (oprright == NULL)
154
rightoid = InvalidOid;
156
rightoid = typenameTypeId(pstate, oprright);
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
* In addition to the operator OIDs themselves, this function can identify
175
* whether the "=" operator is hashable.
177
* Callers can pass NULL pointers for any results they don't care to get.
179
* Note: the results are guaranteed to be exact or binary-compatible matches,
180
* since most callers are not prepared to cope with adding any run-time type
184
get_sort_group_operators(Oid argtype,
185
bool needLT, bool needEQ, bool needGT,
186
Oid *ltOpr, Oid *eqOpr, Oid *gtOpr,
189
TypeCacheEntry *typentry;
197
* Look up the operators using the type cache.
199
* Note: the search algorithm used by typcache.c ensures that the results
200
* are consistent, ie all from matching opclasses.
202
if (isHashable != NULL)
203
cache_flags = TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR |
206
cache_flags = TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR;
208
typentry = lookup_type_cache(argtype, cache_flags);
209
lt_opr = typentry->lt_opr;
210
eq_opr = typentry->eq_opr;
211
gt_opr = typentry->gt_opr;
212
hashable = OidIsValid(typentry->hash_proc);
215
* If the datatype is an array, then we can use array_lt and friends ...
216
* but only if there are suitable operators for the element type.
217
* Likewise, array types are only hashable if the element type is. Testing
218
* all three operator IDs here should be redundant, but let's do it
221
if (lt_opr == ARRAY_LT_OP ||
222
eq_opr == ARRAY_EQ_OP ||
223
gt_opr == ARRAY_GT_OP)
225
Oid elem_type = get_base_element_type(argtype);
227
if (OidIsValid(elem_type))
229
typentry = lookup_type_cache(elem_type, cache_flags);
230
if (!OidIsValid(typentry->eq_opr))
232
/* element type is neither sortable nor hashable */
233
lt_opr = eq_opr = gt_opr = InvalidOid;
235
else if (!OidIsValid(typentry->lt_opr) ||
236
!OidIsValid(typentry->gt_opr))
238
/* element type is hashable but not sortable */
239
lt_opr = gt_opr = InvalidOid;
241
hashable = OidIsValid(typentry->hash_proc);
245
lt_opr = eq_opr = gt_opr = InvalidOid; /* bogus array type? */
250
/* Report errors if needed */
251
if ((needLT && !OidIsValid(lt_opr)) ||
252
(needGT && !OidIsValid(gt_opr)))
254
(errcode(ERRCODE_UNDEFINED_FUNCTION),
255
errmsg("could not identify an ordering operator for type %s",
256
format_type_be(argtype)),
257
errhint("Use an explicit ordering operator or modify the query.")));
258
if (needEQ && !OidIsValid(eq_opr))
260
(errcode(ERRCODE_UNDEFINED_FUNCTION),
261
errmsg("could not identify an equality operator for type %s",
262
format_type_be(argtype))));
264
/* Return results as needed */
272
*isHashable = hashable;
276
/* given operator tuple, return the operator OID */
280
return HeapTupleGetOid(op);
283
/* given operator tuple, return the underlying function's OID */
285
oprfuncid(Operator op)
287
Form_pg_operator pgopform = (Form_pg_operator) GETSTRUCT(op);
289
return pgopform->oprcode;
293
/* binary_oper_exact()
294
* Check for an "exact" match to the specified operand types.
296
* If one operand is an unknown literal, assume it should be taken to be
297
* the same type as the other operand for this purpose. Also, consider
298
* the possibility that the other operand is a domain type that needs to
299
* be reduced to its base type to find an "exact" match.
302
binary_oper_exact(List *opname, Oid arg1, Oid arg2)
305
bool was_unknown = false;
307
/* Unspecified type for one of the arguments? then use the other */
308
if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
313
else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
319
result = OpernameGetOprid(opname, arg1, arg2);
320
if (OidIsValid(result))
325
/* arg1 and arg2 are the same here, need only look at arg1 */
326
Oid basetype = getBaseType(arg1);
328
if (basetype != arg1)
330
result = OpernameGetOprid(opname, basetype, basetype);
331
if (OidIsValid(result))
340
/* oper_select_candidate()
341
* Given the input argtype array and one or more candidates
342
* for the operator, attempt to resolve the conflict.
344
* Returns FUNCDETAIL_NOTFOUND, FUNCDETAIL_MULTIPLE, or FUNCDETAIL_NORMAL.
345
* In the success case the Oid of the best candidate is stored in *operOid.
347
* Note that the caller has already determined that there is no candidate
348
* exactly matching the input argtype(s). Incompatible candidates are not yet
349
* pruned away, however.
351
static FuncDetailCode
352
oper_select_candidate(int nargs,
354
FuncCandidateList candidates,
355
Oid *operOid) /* output argument */
360
* Delete any candidates that cannot actually accept the given input
361
* types, whether directly or by coercion.
363
ncandidates = func_match_argtypes(nargs, input_typeids,
364
candidates, &candidates);
366
/* Done if no candidate or only one candidate survives */
367
if (ncandidates == 0)
369
*operOid = InvalidOid;
370
return FUNCDETAIL_NOTFOUND;
372
if (ncandidates == 1)
374
*operOid = candidates->oid;
375
return FUNCDETAIL_NORMAL;
379
* Use the same heuristics as for ambiguous functions to resolve the
382
candidates = func_select_candidate(nargs, input_typeids, candidates);
386
*operOid = candidates->oid;
387
return FUNCDETAIL_NORMAL;
390
*operOid = InvalidOid;
391
return FUNCDETAIL_MULTIPLE; /* failed to select a best candidate */
395
/* oper() -- search for a binary operator
396
* Given operator name, types of arg1 and arg2, return oper struct.
398
* IMPORTANT: the returned operator (if any) is only promised to be
399
* coercion-compatible with the input datatypes. Do not use this if
400
* you need an exact- or binary-compatible match; see compatible_oper.
402
* If no matching operator found, return NULL if noError is true,
403
* raise an error if it is false. pstate and location are used only to report
404
* the error position; pass NULL/-1 if not available.
406
* NOTE: on success, the returned object is a syscache entry. The caller
407
* must ReleaseSysCache() the entry when done with it.
410
oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId,
411
bool noError, int location)
416
FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
417
HeapTuple tup = NULL;
420
* Try to find the mapping in the lookaside cache.
422
key_ok = make_oper_cache_key(&key, opname, ltypeId, rtypeId);
425
operOid = find_oper_cache_entry(&key);
426
if (OidIsValid(operOid))
428
tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
429
if (HeapTupleIsValid(tup))
430
return (Operator) tup;
435
* First try for an "exact" match.
437
operOid = binary_oper_exact(opname, ltypeId, rtypeId);
438
if (!OidIsValid(operOid))
441
* Otherwise, search for the most suitable candidate.
443
FuncCandidateList clist;
445
/* Get binary operators of given name */
446
clist = OpernameGetCandidates(opname, 'b');
448
/* No operators found? Then fail... */
452
* Unspecified type for one of the arguments? then use the other
453
* (XXX this is probably dead code?)
457
if (rtypeId == InvalidOid)
459
else if (ltypeId == InvalidOid)
461
inputOids[0] = ltypeId;
462
inputOids[1] = rtypeId;
463
fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
467
if (OidIsValid(operOid))
468
tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
470
if (HeapTupleIsValid(tup))
473
make_oper_cache_entry(&key, operOid);
476
op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location);
478
return (Operator) tup;
482
* given an opname and input datatypes, find a compatible binary operator
484
* This is tighter than oper() because it will not return an operator that
485
* requires coercion of the input datatypes (but binary-compatible operators
486
* are accepted). Otherwise, the semantics are the same.
489
compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2,
490
bool noError, int location)
493
Form_pg_operator opform;
495
/* oper() will find the best available match */
496
optup = oper(pstate, op, arg1, arg2, noError, location);
497
if (optup == (Operator) NULL)
498
return (Operator) NULL; /* must be noError case */
500
/* but is it good enough? */
501
opform = (Form_pg_operator) GETSTRUCT(optup);
502
if (IsBinaryCoercible(arg1, opform->oprleft) &&
503
IsBinaryCoercible(arg2, opform->oprright))
507
ReleaseSysCache(optup);
511
(errcode(ERRCODE_UNDEFINED_FUNCTION),
512
errmsg("operator requires run-time type coercion: %s",
513
op_signature_string(op, 'b', arg1, arg2)),
514
parser_errposition(pstate, location)));
516
return (Operator) NULL;
519
/* compatible_oper_opid() -- get OID of a binary operator
521
* This is a convenience routine that extracts only the operator OID
522
* from the result of compatible_oper(). InvalidOid is returned if the
523
* lookup fails and noError is true.
526
compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
531
optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
534
result = oprid(optup);
535
ReleaseSysCache(optup);
542
/* right_oper() -- search for a unary right operator (postfix operator)
543
* Given operator name and type of arg, return oper struct.
545
* IMPORTANT: the returned operator (if any) is only promised to be
546
* coercion-compatible with the input datatype. Do not use this if
547
* you need an exact- or binary-compatible match.
549
* If no matching operator found, return NULL if noError is true,
550
* raise an error if it is false. pstate and location are used only to report
551
* the error position; pass NULL/-1 if not available.
553
* NOTE: on success, the returned object is a syscache entry. The caller
554
* must ReleaseSysCache() the entry when done with it.
557
right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
562
FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
563
HeapTuple tup = NULL;
566
* Try to find the mapping in the lookaside cache.
568
key_ok = make_oper_cache_key(&key, op, arg, InvalidOid);
571
operOid = find_oper_cache_entry(&key);
572
if (OidIsValid(operOid))
574
tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
575
if (HeapTupleIsValid(tup))
576
return (Operator) tup;
581
* First try for an "exact" match.
583
operOid = OpernameGetOprid(op, arg, InvalidOid);
584
if (!OidIsValid(operOid))
587
* Otherwise, search for the most suitable candidate.
589
FuncCandidateList clist;
591
/* Get postfix operators of given name */
592
clist = OpernameGetCandidates(op, 'r');
594
/* No operators found? Then fail... */
598
* We must run oper_select_candidate even if only one candidate,
599
* otherwise we may falsely return a non-type-compatible operator.
601
fdresult = oper_select_candidate(1, &arg, clist, &operOid);
605
if (OidIsValid(operOid))
606
tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
608
if (HeapTupleIsValid(tup))
611
make_oper_cache_entry(&key, operOid);
614
op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location);
616
return (Operator) tup;
620
/* left_oper() -- search for a unary left operator (prefix operator)
621
* Given operator name and type of arg, return oper struct.
623
* IMPORTANT: the returned operator (if any) is only promised to be
624
* coercion-compatible with the input datatype. Do not use this if
625
* you need an exact- or binary-compatible match.
627
* If no matching operator found, return NULL if noError is true,
628
* raise an error if it is false. pstate and location are used only to report
629
* the error position; pass NULL/-1 if not available.
631
* NOTE: on success, the returned object is a syscache entry. The caller
632
* must ReleaseSysCache() the entry when done with it.
635
left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
640
FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
641
HeapTuple tup = NULL;
644
* Try to find the mapping in the lookaside cache.
646
key_ok = make_oper_cache_key(&key, op, InvalidOid, arg);
649
operOid = find_oper_cache_entry(&key);
650
if (OidIsValid(operOid))
652
tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
653
if (HeapTupleIsValid(tup))
654
return (Operator) tup;
659
* First try for an "exact" match.
661
operOid = OpernameGetOprid(op, InvalidOid, arg);
662
if (!OidIsValid(operOid))
665
* Otherwise, search for the most suitable candidate.
667
FuncCandidateList clist;
669
/* Get prefix operators of given name */
670
clist = OpernameGetCandidates(op, 'l');
672
/* No operators found? Then fail... */
676
* The returned list has args in the form (0, oprright). Move the
677
* useful data into args[0] to keep oper_select_candidate simple.
678
* XXX we are assuming here that we may scribble on the list!
680
FuncCandidateList clisti;
682
for (clisti = clist; clisti != NULL; clisti = clisti->next)
684
clisti->args[0] = clisti->args[1];
688
* We must run oper_select_candidate even if only one candidate,
689
* otherwise we may falsely return a non-type-compatible operator.
691
fdresult = oper_select_candidate(1, &arg, clist, &operOid);
695
if (OidIsValid(operOid))
696
tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
698
if (HeapTupleIsValid(tup))
701
make_oper_cache_entry(&key, operOid);
704
op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location);
706
return (Operator) tup;
710
* op_signature_string
711
* Build a string representing an operator name, including arg type(s).
712
* The result is something like "integer + integer".
714
* This is typically used in the construction of operator-not-found error
718
op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
720
StringInfoData argbuf;
722
initStringInfo(&argbuf);
725
appendStringInfo(&argbuf, "%s ", format_type_be(arg1));
727
appendStringInfoString(&argbuf, NameListToString(op));
730
appendStringInfo(&argbuf, " %s", format_type_be(arg2));
732
return argbuf.data; /* return palloc'd string buffer */
736
* op_error - utility routine to complain about an unresolvable operator
739
op_error(ParseState *pstate, List *op, char oprkind,
741
FuncDetailCode fdresult, int location)
743
if (fdresult == FUNCDETAIL_MULTIPLE)
745
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
746
errmsg("operator is not unique: %s",
747
op_signature_string(op, oprkind, arg1, arg2)),
748
errhint("Could not choose a best candidate operator. "
749
"You might need to add explicit type casts."),
750
parser_errposition(pstate, location)));
753
(errcode(ERRCODE_UNDEFINED_FUNCTION),
754
errmsg("operator does not exist: %s",
755
op_signature_string(op, oprkind, arg1, arg2)),
756
errhint("No operator matches the given name and argument type(s). "
757
"You might need to add explicit type casts."),
758
parser_errposition(pstate, location)));
763
* Operator expression construction.
765
* Transform operator expression ensuring type compatibility.
766
* This is where some type conversion happens.
768
* As with coerce_type, pstate may be NULL if no special unknown-Param
769
* processing is wanted.
772
make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
778
Form_pg_operator opform;
779
Oid actual_arg_types[2];
780
Oid declared_arg_types[2];
786
/* Select the operator */
790
ltypeId = exprType(ltree);
791
rtypeId = InvalidOid;
792
tup = right_oper(pstate, opname, ltypeId, false, location);
794
else if (ltree == NULL)
797
rtypeId = exprType(rtree);
798
ltypeId = InvalidOid;
799
tup = left_oper(pstate, opname, rtypeId, false, location);
803
/* otherwise, binary operator */
804
ltypeId = exprType(ltree);
805
rtypeId = exprType(rtree);
806
tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
809
opform = (Form_pg_operator) GETSTRUCT(tup);
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,
820
parser_errposition(pstate, location)));
822
/* Do typecasting and build the expression tree */
826
args = list_make1(ltree);
827
actual_arg_types[0] = ltypeId;
828
declared_arg_types[0] = opform->oprleft;
831
else if (ltree == NULL)
834
args = list_make1(rtree);
835
actual_arg_types[0] = rtypeId;
836
declared_arg_types[0] = opform->oprright;
841
/* otherwise, binary operator */
842
args = list_make2(ltree, rtree);
843
actual_arg_types[0] = ltypeId;
844
actual_arg_types[1] = rtypeId;
845
declared_arg_types[0] = opform->oprleft;
846
declared_arg_types[1] = opform->oprright;
851
* enforce consistency with polymorphic argument and return types,
852
* possibly adjusting return type or declared_arg_types (which will be
853
* used as the cast destination by make_fn_arguments)
855
rettype = enforce_generic_type_consistency(actual_arg_types,
861
/* perform the necessary typecasting of arguments */
862
make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
864
/* and build the expression node */
865
result = makeNode(OpExpr);
866
result->opno = oprid(tup);
867
result->opfuncid = opform->oprcode;
868
result->opresulttype = rettype;
869
result->opretset = get_func_retset(opform->oprcode);
870
/* opcollid and inputcollid will be set by parse_collate.c */
872
result->location = location;
874
ReleaseSysCache(tup);
876
return (Expr *) result;
880
* make_scalar_array_op()
881
* Build expression tree for "scalar op ANY/ALL (array)" construct.
884
make_scalar_array_op(ParseState *pstate, List *opname,
886
Node *ltree, Node *rtree,
894
Form_pg_operator opform;
895
Oid actual_arg_types[2];
896
Oid declared_arg_types[2];
899
ScalarArrayOpExpr *result;
901
ltypeId = exprType(ltree);
902
atypeId = exprType(rtree);
905
* The right-hand input of the operator will be the element type of the
906
* array. However, if we currently have just an untyped literal on the
907
* right, stay with that and hope we can resolve the operator.
909
if (atypeId == UNKNOWNOID)
910
rtypeId = UNKNOWNOID;
913
rtypeId = get_base_element_type(atypeId);
914
if (!OidIsValid(rtypeId))
916
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
917
errmsg("op ANY/ALL (array) requires array on right side"),
918
parser_errposition(pstate, location)));
921
/* Now resolve the operator */
922
tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
923
opform = (Form_pg_operator) GETSTRUCT(tup);
925
/* Check it's not a shell */
926
if (!RegProcedureIsValid(opform->oprcode))
928
(errcode(ERRCODE_UNDEFINED_FUNCTION),
929
errmsg("operator is only a shell: %s",
930
op_signature_string(opname,
934
parser_errposition(pstate, location)));
936
args = list_make2(ltree, rtree);
937
actual_arg_types[0] = ltypeId;
938
actual_arg_types[1] = rtypeId;
939
declared_arg_types[0] = opform->oprleft;
940
declared_arg_types[1] = opform->oprright;
943
* enforce consistency with polymorphic argument and return types,
944
* possibly adjusting return type or declared_arg_types (which will be
945
* used as the cast destination by make_fn_arguments)
947
rettype = enforce_generic_type_consistency(actual_arg_types,
954
* Check that operator result is boolean
956
if (rettype != BOOLOID)
958
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
959
errmsg("op ANY/ALL (array) requires operator to yield boolean"),
960
parser_errposition(pstate, location)));
961
if (get_func_retset(opform->oprcode))
963
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
964
errmsg("op ANY/ALL (array) requires operator not to return a set"),
965
parser_errposition(pstate, location)));
968
* Now switch back to the array type on the right, arranging for any
969
* needed cast to be applied. Beware of polymorphic operators here;
970
* enforce_generic_type_consistency may or may not have replaced a
971
* polymorphic type with a real one.
973
if (IsPolymorphicType(declared_arg_types[1]))
975
/* assume the actual array type is OK */
976
res_atypeId = atypeId;
980
res_atypeId = get_array_type(declared_arg_types[1]);
981
if (!OidIsValid(res_atypeId))
983
(errcode(ERRCODE_UNDEFINED_OBJECT),
984
errmsg("could not find array type for data type %s",
985
format_type_be(declared_arg_types[1])),
986
parser_errposition(pstate, location)));
988
actual_arg_types[1] = atypeId;
989
declared_arg_types[1] = res_atypeId;
991
/* perform the necessary typecasting of arguments */
992
make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
994
/* and build the expression node */
995
result = makeNode(ScalarArrayOpExpr);
996
result->opno = oprid(tup);
997
result->opfuncid = opform->oprcode;
998
result->useOr = useOr;
999
/* inputcollid will be set by parse_collate.c */
1000
result->args = args;
1001
result->location = location;
1003
ReleaseSysCache(tup);
1005
return (Expr *) result;
1010
* Lookaside cache to speed operator lookup. Possibly this should be in
1011
* a separate module under utils/cache/ ?
1013
* The idea here is that the mapping from operator name and given argument
1014
* types is constant for a given search path (or single specified schema OID)
1015
* so long as the contents of pg_operator and pg_cast don't change. And that
1016
* mapping is pretty expensive to compute, especially for ambiguous operators;
1017
* this is mainly because there are a *lot* of instances of popular operator
1018
* names such as "=", and we have to check each one to see which is the
1019
* best match. So once we have identified the correct mapping, we save it
1020
* in a cache that need only be flushed on pg_operator or pg_cast change.
1021
* (pg_cast must be considered because changes in the set of implicit casts
1022
* affect the set of applicable operators for any given input datatype.)
1024
* XXX in principle, ALTER TABLE ... INHERIT could affect the mapping as
1025
* well, but we disregard that since there's no convenient way to find out
1026
* about it, and it seems a pretty far-fetched corner-case anyway.
1028
* Note: at some point it might be worth doing a similar cache for function
1029
* lookups. However, the potential gain is a lot less since (a) function
1030
* names are generally not overloaded as heavily as operator names, and
1031
* (b) we'd have to flush on pg_proc updates, which are probably a good
1032
* deal more common than pg_operator updates.
1035
/* The operator cache hashtable */
1036
static HTAB *OprCacheHash = NULL;
1040
* make_oper_cache_key
1041
* Fill the lookup key struct given operator name and arg types.
1043
* Returns TRUE if successful, FALSE if the search_path overflowed
1044
* (hence no caching is possible).
1047
make_oper_cache_key(OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId)
1052
/* deconstruct the name list */
1053
DeconstructQualifiedName(opname, &schemaname, &opername);
1055
/* ensure zero-fill for stable hashing */
1056
MemSet(key, 0, sizeof(OprCacheKey));
1058
/* save operator name and input types into key */
1059
strlcpy(key->oprname, opername, NAMEDATALEN);
1060
key->left_arg = ltypeId;
1061
key->right_arg = rtypeId;
1065
/* search only in exact schema given */
1066
key->search_path[0] = LookupExplicitNamespace(schemaname);
1070
/* get the active search path */
1071
if (fetch_search_path_array(key->search_path,
1072
MAX_CACHED_PATH_LEN) > MAX_CACHED_PATH_LEN)
1073
return false; /* oops, didn't fit */
1080
* find_oper_cache_entry
1082
* Look for a cache entry matching the given key. If found, return the
1083
* contained operator OID, else return InvalidOid.
1086
find_oper_cache_entry(OprCacheKey *key)
1088
OprCacheEntry *oprentry;
1090
if (OprCacheHash == NULL)
1092
/* First time through: initialize the hash table */
1095
MemSet(&ctl, 0, sizeof(ctl));
1096
ctl.keysize = sizeof(OprCacheKey);
1097
ctl.entrysize = sizeof(OprCacheEntry);
1098
ctl.hash = tag_hash;
1099
OprCacheHash = hash_create("Operator lookup cache", 256,
1100
&ctl, HASH_ELEM | HASH_FUNCTION);
1102
/* Arrange to flush cache on pg_operator and pg_cast changes */
1103
CacheRegisterSyscacheCallback(OPERNAMENSP,
1104
InvalidateOprCacheCallBack,
1106
CacheRegisterSyscacheCallback(CASTSOURCETARGET,
1107
InvalidateOprCacheCallBack,
1111
/* Look for an existing entry */
1112
oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1115
if (oprentry == NULL)
1118
return oprentry->opr_oid;
1122
* make_oper_cache_entry
1124
* Insert a cache entry for the given key.
1127
make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
1129
OprCacheEntry *oprentry;
1131
Assert(OprCacheHash != NULL);
1133
oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1136
oprentry->opr_oid = opr_oid;
1140
* Callback for pg_operator and pg_cast inval events
1143
InvalidateOprCacheCallBack(Datum arg, int cacheid, ItemPointer tuplePtr)
1145
HASH_SEQ_STATUS status;
1146
OprCacheEntry *hentry;
1148
Assert(OprCacheHash != NULL);
1150
/* Currently we just flush all entries; hard to be smarter ... */
1151
hash_seq_init(&status, OprCacheHash);
1153
while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
1155
if (hash_search(OprCacheHash,
1156
(void *) &hentry->key,
1157
HASH_REMOVE, NULL) == NULL)
1158
elog(ERROR, "hash table corrupted");