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