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