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