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 3077 : LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
102 : bool noError, int location)
103 : {
104 : Oid result;
105 :
106 3077 : result = OpernameGetOprid(opername, oprleft, oprright);
107 3077 : if (OidIsValid(result))
108 2641 : return result;
109 :
110 : /* we don't use op_error here because only an exact match is wanted */
111 436 : if (!noError)
112 : {
113 24 : if (!OidIsValid(oprright))
114 6 : ereport(ERROR,
115 : (errcode(ERRCODE_SYNTAX_ERROR),
116 : errmsg("postfix operators are not supported"),
117 : parser_errposition(pstate, location)));
118 :
119 18 : 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 412 : 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 1144 : 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 1144 : oprleft = linitial_node(TypeName, oper->objargs);
144 1144 : oprright = lsecond_node(TypeName, oper->objargs);
145 :
146 1144 : if (oprleft == NULL)
147 16 : leftoid = InvalidOid;
148 : else
149 1128 : leftoid = LookupTypeNameOid(NULL, oprleft, noError);
150 :
151 1141 : if (oprright == NULL)
152 6 : rightoid = InvalidOid;
153 : else
154 1135 : rightoid = LookupTypeNameOid(NULL, oprright, noError);
155 :
156 1138 : 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 145836 : 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 145836 : if (isHashable != NULL)
201 83862 : cache_flags = TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR |
202 : TYPECACHE_HASH_PROC;
203 : else
204 61974 : cache_flags = TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR;
205 :
206 145836 : typentry = lookup_type_cache(argtype, cache_flags);
207 145836 : lt_opr = typentry->lt_opr;
208 145836 : eq_opr = typentry->eq_opr;
209 145836 : gt_opr = typentry->gt_opr;
210 145836 : hashable = OidIsValid(typentry->hash_proc);
211 :
212 : /* Report errors if needed */
213 145836 : if ((needLT && !OidIsValid(lt_opr)) ||
214 1825 : (needGT && !OidIsValid(gt_opr)))
215 3 : 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 145833 : 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 145833 : if (ltOpr)
228 144008 : *ltOpr = lt_opr;
229 145833 : if (eqOpr)
230 145833 : *eqOpr = eq_opr;
231 145833 : if (gtOpr)
232 1825 : *gtOpr = gt_opr;
233 145833 : if (isHashable)
234 83859 : *isHashable = hashable;
235 145833 : }
236 :
237 :
238 : /* given operator tuple, return the operator OID */
239 : Oid
240 385888 : oprid(Operator op)
241 : {
242 385888 : 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 44200 : binary_oper_exact(List *opname, Oid arg1, Oid arg2)
265 : {
266 : Oid result;
267 44200 : bool was_unknown = false;
268 :
269 : /* Unspecified type for one of the arguments? then use the other */
270 44200 : if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
271 : {
272 2143 : arg1 = arg2;
273 2143 : was_unknown = true;
274 : }
275 42057 : else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
276 : {
277 11557 : arg2 = arg1;
278 11557 : was_unknown = true;
279 : }
280 :
281 44200 : result = OpernameGetOprid(opname, arg1, arg2);
282 44200 : if (OidIsValid(result))
283 33967 : return result;
284 :
285 10233 : if (was_unknown)
286 : {
287 : /* arg1 and arg2 are the same here, need only look at arg1 */
288 2506 : Oid basetype = getBaseType(arg1);
289 :
290 2506 : if (basetype != arg1)
291 : {
292 169 : result = OpernameGetOprid(opname, basetype, basetype);
293 169 : if (OidIsValid(result))
294 32 : return result;
295 : }
296 : }
297 :
298 10201 : 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 10219 : 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 10219 : ncandidates = func_match_argtypes(nargs, input_typeids,
326 : candidates, &candidates);
327 :
328 : /* Done if no candidate or only one candidate survives */
329 10219 : if (ncandidates == 0)
330 : {
331 61 : *operOid = InvalidOid;
332 61 : return FUNCDETAIL_NOTFOUND;
333 : }
334 10158 : if (ncandidates == 1)
335 : {
336 7010 : *operOid = candidates->oid;
337 7010 : return FUNCDETAIL_NORMAL;
338 : }
339 :
340 : /*
341 : * Use the same heuristics as for ambiguous functions to resolve the
342 : * conflict.
343 : */
344 3148 : candidates = func_select_candidate(nargs, input_typeids, candidates);
345 :
346 3148 : if (candidates)
347 : {
348 3145 : *operOid = candidates->oid;
349 3145 : return FUNCDETAIL_NORMAL;
350 : }
351 :
352 3 : *operOid = InvalidOid;
353 3 : 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 385315 : 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 385315 : int fgc_flags = 0;
379 385315 : FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
380 385315 : HeapTuple tup = NULL;
381 :
382 : /*
383 : * Try to find the mapping in the lookaside cache.
384 : */
385 385315 : key_ok = make_oper_cache_key(pstate, &key, opname, ltypeId, rtypeId, location);
386 :
387 385315 : if (key_ok)
388 : {
389 385315 : operOid = find_oper_cache_entry(&key);
390 385315 : if (OidIsValid(operOid))
391 : {
392 341115 : tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
393 341115 : if (HeapTupleIsValid(tup))
394 341115 : return (Operator) tup;
395 : }
396 : }
397 :
398 : /*
399 : * First try for an "exact" match.
400 : */
401 44200 : operOid = binary_oper_exact(opname, ltypeId, rtypeId);
402 44200 : 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 10201 : clist = OpernameGetCandidates(opname, 'b', false, &fgc_flags);
411 :
412 : /* No operators found? Then fail... */
413 10201 : 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 10201 : if (rtypeId == InvalidOid)
422 0 : rtypeId = ltypeId;
423 10201 : else if (ltypeId == InvalidOid)
424 0 : ltypeId = rtypeId;
425 10201 : inputOids[0] = ltypeId;
426 10201 : inputOids[1] = rtypeId;
427 10201 : fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
428 : }
429 : }
430 :
431 44200 : if (OidIsValid(operOid))
432 44139 : tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
433 :
434 44200 : if (HeapTupleIsValid(tup))
435 : {
436 44139 : if (key_ok)
437 44139 : make_oper_cache_entry(&key, operOid);
438 : }
439 61 : else if (!noError)
440 56 : op_error(pstate, opname, ltypeId, rtypeId,
441 : fdresult, fgc_flags, location);
442 :
443 44144 : 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 284 : 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 284 : optup = oper(pstate, op, arg1, arg2, noError, location);
462 284 : if (optup == (Operator) NULL)
463 0 : return (Operator) NULL; /* must be noError case */
464 :
465 : /* but is it good enough? */
466 284 : opform = (Form_pg_operator) GETSTRUCT(optup);
467 568 : if (IsBinaryCoercible(arg1, opform->oprleft) &&
468 284 : IsBinaryCoercible(arg2, opform->oprright))
469 284 : 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 284 : compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
492 : {
493 : Operator optup;
494 : Oid result;
495 :
496 284 : optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
497 284 : if (optup != NULL)
498 : {
499 284 : result = oprid(optup);
500 284 : ReleaseSysCache(optup);
501 284 : 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 649 : left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
523 : {
524 : Oid operOid;
525 : OprCacheKey key;
526 : bool key_ok;
527 649 : int fgc_flags = 0;
528 649 : FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
529 649 : HeapTuple tup = NULL;
530 :
531 : /*
532 : * Try to find the mapping in the lookaside cache.
533 : */
534 649 : key_ok = make_oper_cache_key(pstate, &key, op, InvalidOid, arg, location);
535 :
536 649 : if (key_ok)
537 : {
538 649 : operOid = find_oper_cache_entry(&key);
539 649 : if (OidIsValid(operOid))
540 : {
541 409 : tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
542 409 : if (HeapTupleIsValid(tup))
543 409 : return (Operator) tup;
544 : }
545 : }
546 :
547 : /*
548 : * First try for an "exact" match.
549 : */
550 240 : operOid = OpernameGetOprid(op, InvalidOid, arg);
551 240 : 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 24 : clist = OpernameGetCandidates(op, 'l', false, &fgc_flags);
560 :
561 : /* No operators found? Then fail... */
562 24 : 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 59 : for (clisti = clist; clisti != NULL; clisti = clisti->next)
572 : {
573 41 : 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 18 : fdresult = oper_select_candidate(1, &arg, clist, &operOid);
581 : }
582 : }
583 :
584 240 : if (OidIsValid(operOid))
585 231 : tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
586 :
587 240 : if (HeapTupleIsValid(tup))
588 : {
589 231 : if (key_ok)
590 231 : make_oper_cache_entry(&key, operOid);
591 : }
592 9 : else if (!noError)
593 9 : op_error(pstate, op, InvalidOid, arg,
594 : fdresult, fgc_flags, location);
595 :
596 231 : 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 83 : op_signature_string(List *op, Oid arg1, Oid arg2)
609 : {
610 : StringInfoData argbuf;
611 :
612 83 : initStringInfo(&argbuf);
613 :
614 83 : if (OidIsValid(arg1))
615 68 : appendStringInfo(&argbuf, "%s ", format_type_be(arg1));
616 :
617 83 : appendStringInfoString(&argbuf, NameListToString(op));
618 :
619 83 : appendStringInfo(&argbuf, " %s", format_type_be(arg2));
620 :
621 83 : 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 65 : op_error(ParseState *pstate, List *op,
629 : Oid arg1, Oid arg2,
630 : FuncDetailCode fdresult, int fgc_flags, int location)
631 : {
632 65 : if (fdresult == FUNCDETAIL_MULTIPLE)
633 3 : 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 62 : 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 62 : 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 62 : if (!(fgc_flags & FGC_NAME_VISIBLE))
667 : {
668 6 : if (fgc_flags & FGC_SCHEMA_GIVEN)
669 0 : return 0; /* schema-qualified name */
670 6 : else if (!(fgc_flags & FGC_NAME_EXISTS))
671 3 : return errdetail("There is no operator of that name.");
672 : else
673 3 : 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 56 : if (is_unary_op)
680 : {
681 3 : (void) errdetail("No operator of that name accepts the given argument type.");
682 3 : return errhint("You might need to add an explicit type cast.");
683 : }
684 : else
685 : {
686 53 : (void) errdetail("No operator of that name accepts the given argument types.");
687 53 : 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 333826 : 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 333826 : 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 333826 : if (ltree == NULL)
726 : {
727 : /* prefix operator */
728 634 : rtypeId = exprType(rtree);
729 634 : ltypeId = InvalidOid;
730 634 : tup = left_oper(pstate, opname, rtypeId, false, location);
731 : }
732 : else
733 : {
734 : /* otherwise, binary operator */
735 333192 : ltypeId = exprType(ltree);
736 333192 : rtypeId = exprType(rtree);
737 333192 : tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
738 : }
739 :
740 333761 : opform = (Form_pg_operator) GETSTRUCT(tup);
741 :
742 : /* Check it's not a shell */
743 333761 : 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 333761 : if (ltree == NULL)
754 : {
755 : /* prefix operator */
756 625 : args = list_make1(rtree);
757 625 : actual_arg_types[0] = rtypeId;
758 625 : declared_arg_types[0] = opform->oprright;
759 625 : nargs = 1;
760 : }
761 : else
762 : {
763 : /* otherwise, binary operator */
764 333136 : args = list_make2(ltree, rtree);
765 333136 : actual_arg_types[0] = ltypeId;
766 333136 : actual_arg_types[1] = rtypeId;
767 333136 : declared_arg_types[0] = opform->oprleft;
768 333136 : declared_arg_types[1] = opform->oprright;
769 333136 : 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 333761 : 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 333761 : make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
785 :
786 : /* and build the expression node */
787 333758 : result = makeNode(OpExpr);
788 333758 : result->opno = oprid(tup);
789 333758 : result->opfuncid = opform->oprcode;
790 333758 : result->opresulttype = rettype;
791 333758 : result->opretset = get_func_retset(opform->oprcode);
792 : /* opcollid and inputcollid will be set by parse_collate.c */
793 333758 : result->args = args;
794 333758 : result->location = location;
795 :
796 : /* if it returns a set, check that's OK */
797 333758 : if (result->opretset)
798 : {
799 3 : check_srf_call_placement(pstate, last_srf, location);
800 : /* ... and remember it for error checks at higher levels */
801 3 : pstate->p_last_srf = (Node *) result;
802 : }
803 :
804 333758 : ReleaseSysCache(tup);
805 :
806 333758 : 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 18872 : 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 18872 : ltypeId = exprType(ltree);
832 18872 : 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 18872 : if (atypeId == UNKNOWNOID)
840 111 : rtypeId = UNKNOWNOID;
841 : else
842 : {
843 18761 : rtypeId = get_base_element_type(atypeId);
844 18761 : if (!OidIsValid(rtypeId))
845 3 : 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 18869 : tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
853 18869 : opform = (Form_pg_operator) GETSTRUCT(tup);
854 :
855 : /* Check it's not a shell */
856 18869 : 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 18869 : args = list_make2(ltree, rtree);
866 18869 : actual_arg_types[0] = ltypeId;
867 18869 : actual_arg_types[1] = rtypeId;
868 18869 : declared_arg_types[0] = opform->oprleft;
869 18869 : 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 18869 : 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 18869 : if (rettype != BOOLOID)
886 3 : 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 18866 : 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 18866 : if (IsPolymorphicType(declared_arg_types[1]))
903 : {
904 : /* assume the actual array type is OK */
905 20 : res_atypeId = atypeId;
906 : }
907 : else
908 : {
909 18846 : res_atypeId = get_array_type(declared_arg_types[1]);
910 18846 : 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 18866 : actual_arg_types[1] = atypeId;
918 18866 : declared_arg_types[1] = res_atypeId;
919 :
920 : /* perform the necessary typecasting of arguments */
921 18866 : make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
922 :
923 : /* and build the expression node */
924 18866 : result = makeNode(ScalarArrayOpExpr);
925 18866 : result->opno = oprid(tup);
926 18866 : result->opfuncid = opform->oprcode;
927 18866 : result->hashfuncid = InvalidOid;
928 18866 : result->negfuncid = InvalidOid;
929 18866 : result->useOr = useOr;
930 : /* inputcollid will be set by parse_collate.c */
931 18866 : result->args = args;
932 18866 : result->location = location;
933 :
934 18866 : ReleaseSysCache(tup);
935 :
936 18866 : 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 385964 : 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 385964 : DeconstructQualifiedName(opname, &schemaname, &opername);
989 :
990 : /* ensure zero-fill for stable hashing */
991 6947352 : MemSet(key, 0, sizeof(OprCacheKey));
992 :
993 : /* save operator name and input types into key */
994 385964 : strlcpy(key->oprname, opername, NAMEDATALEN);
995 385964 : key->left_arg = ltypeId;
996 385964 : key->right_arg = rtypeId;
997 :
998 385964 : if (schemaname)
999 : {
1000 : ParseCallbackState pcbstate;
1001 :
1002 : /* search only in exact schema given */
1003 8309 : setup_parser_errposition_callback(&pcbstate, pstate, location);
1004 8309 : key->search_path[0] = LookupExplicitNamespace(schemaname, false);
1005 8309 : cancel_parser_errposition_callback(&pcbstate);
1006 : }
1007 : else
1008 : {
1009 : /* get the active search path */
1010 377655 : 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 385964 : 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 385964 : find_oper_cache_entry(OprCacheKey *key)
1026 : {
1027 : OprCacheEntry *oprentry;
1028 :
1029 385964 : if (OprCacheHash == NULL)
1030 : {
1031 : /* First time through: initialize the hash table */
1032 : HASHCTL ctl;
1033 :
1034 5861 : ctl.keysize = sizeof(OprCacheKey);
1035 5861 : ctl.entrysize = sizeof(OprCacheEntry);
1036 5861 : 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 5861 : CacheRegisterSyscacheCallback(OPERNAMENSP,
1041 : InvalidateOprCacheCallBack,
1042 : (Datum) 0);
1043 5861 : CacheRegisterSyscacheCallback(CASTSOURCETARGET,
1044 : InvalidateOprCacheCallBack,
1045 : (Datum) 0);
1046 : }
1047 :
1048 : /* Look for an existing entry */
1049 385964 : oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1050 : key,
1051 : HASH_FIND, NULL);
1052 385964 : if (oprentry == NULL)
1053 44440 : return InvalidOid;
1054 :
1055 341524 : 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 44370 : make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
1065 : {
1066 : OprCacheEntry *oprentry;
1067 :
1068 : Assert(OprCacheHash != NULL);
1069 :
1070 44370 : oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
1071 : key,
1072 : HASH_ENTER, NULL);
1073 44370 : oprentry->opr_oid = opr_oid;
1074 44370 : }
1075 :
1076 : /*
1077 : * Callback for pg_operator and pg_cast inval events
1078 : */
1079 : static void
1080 6521 : 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 6521 : hash_seq_init(&status, OprCacheHash);
1090 :
1091 15507 : while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
1092 : {
1093 8986 : if (hash_search(OprCacheHash,
1094 8986 : &hentry->key,
1095 : HASH_REMOVE, NULL) == NULL)
1096 0 : elog(ERROR, "hash table corrupted");
1097 : }
1098 6521 : }
|