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