OSDN Git Service

51d780dc5bbc7dfe828b8e8b612c8a93ae4f6114
[pg-rex/syncrep.git] / src / backend / parser / parse_oper.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_oper.c
4  *              handle operator things for parser
5  *
6  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.77 2003/11/29 19:51:52 pgsql Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "postgres.h"
17
18 #include "catalog/pg_operator.h"
19 #include "lib/stringinfo.h"
20 #include "parser/parse_coerce.h"
21 #include "parser/parse_expr.h"
22 #include "parser/parse_func.h"
23 #include "parser/parse_oper.h"
24 #include "parser/parse_type.h"
25 #include "utils/builtins.h"
26 #include "utils/fmgroids.h"
27 #include "utils/lsyscache.h"
28 #include "utils/syscache.h"
29 #include "utils/typcache.h"
30
31
32 static Oid binary_oper_exact(Oid arg1, Oid arg2,
33                                   FuncCandidateList candidates);
34 static FuncDetailCode oper_select_candidate(int nargs,
35                                           Oid *input_typeids,
36                                           FuncCandidateList candidates,
37                                           Oid *operOid);
38 static const char *op_signature_string(List *op, char oprkind,
39                                         Oid arg1, Oid arg2);
40 static void op_error(List *op, char oprkind, Oid arg1, Oid arg2,
41                  FuncDetailCode fdresult);
42
43
44 /*
45  * LookupOperName
46  *              Given a possibly-qualified operator name and exact input datatypes,
47  *              look up the operator.
48  *
49  * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for
50  * a postfix op.
51  *
52  * If the operator name is not schema-qualified, it is sought in the current
53  * namespace search path.
54  *
55  * If the operator is not found, we return InvalidOid if noError is true,
56  * else raise an error.
57  */
58 Oid
59 LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError)
60 {
61         FuncCandidateList clist;
62         char            oprkind;
63
64         if (!OidIsValid(oprleft))
65                 oprkind = 'l';
66         else if (!OidIsValid(oprright))
67                 oprkind = 'r';
68         else
69                 oprkind = 'b';
70
71         clist = OpernameGetCandidates(opername, oprkind);
72
73         while (clist)
74         {
75                 if (clist->args[0] == oprleft && clist->args[1] == oprright)
76                         return clist->oid;
77                 clist = clist->next;
78         }
79
80         /* we don't use op_error here because only an exact match is wanted */
81         if (!noError)
82                 ereport(ERROR,
83                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
84                                  errmsg("operator does not exist: %s",
85                                                 op_signature_string(opername, oprkind,
86                                                                                         oprleft, oprright))));
87
88         return InvalidOid;
89 }
90
91 /*
92  * LookupOperNameTypeNames
93  *              Like LookupOperName, but the argument types are specified by
94  *              TypeName nodes.
95  *
96  * Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op.
97  */
98 Oid
99 LookupOperNameTypeNames(List *opername, TypeName *oprleft,
100                                                 TypeName *oprright, bool noError)
101 {
102         Oid                     leftoid,
103                                 rightoid;
104
105         if (oprleft == NULL)
106                 leftoid = InvalidOid;
107         else
108         {
109                 leftoid = LookupTypeName(oprleft);
110                 if (!OidIsValid(leftoid))
111                         ereport(ERROR,
112                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
113                                          errmsg("type %s does not exist",
114                                                         TypeNameToString(oprleft))));
115         }
116         if (oprright == NULL)
117                 rightoid = InvalidOid;
118         else
119         {
120                 rightoid = LookupTypeName(oprright);
121                 if (!OidIsValid(rightoid))
122                         ereport(ERROR,
123                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
124                                          errmsg("type %s does not exist",
125                                                         TypeNameToString(oprright))));
126         }
127
128         return LookupOperName(opername, leftoid, rightoid, noError);
129 }
130
131 /*
132  * equality_oper - identify a suitable equality operator for a datatype
133  *
134  * On failure, return NULL if noError, else report a standard error
135  */
136 Operator
137 equality_oper(Oid argtype, bool noError)
138 {
139         TypeCacheEntry *typentry;
140         Oid                     oproid;
141         Operator        optup;
142
143         /*
144          * Look for an "=" operator for the datatype.  We require it to be
145          * an exact or binary-compatible match, since most callers are not
146          * prepared to cope with adding any run-time type coercion steps.
147          */
148         typentry = lookup_type_cache(argtype, TYPECACHE_EQ_OPR);
149         oproid = typentry->eq_opr;
150
151         /*
152          * If the datatype is an array, then we can use array_eq ... but only
153          * if there is a suitable equality operator for the element type.
154          * (This check is not in the raw typcache.c code ... should it be?)
155          */
156         if (oproid == ARRAY_EQ_OP)
157         {
158                 Oid             elem_type = get_element_type(argtype);
159
160                 if (OidIsValid(elem_type))
161                 {
162                         optup = equality_oper(elem_type, true);
163                         if (optup != NULL)
164                                 ReleaseSysCache(optup);
165                         else
166                                 oproid = InvalidOid;    /* element type has no "=" */
167                 }
168                 else
169                         oproid = InvalidOid;            /* bogus array type? */
170         }
171
172         if (OidIsValid(oproid))
173         {
174                 optup = SearchSysCache(OPEROID,
175                                                            ObjectIdGetDatum(oproid),
176                                                            0, 0, 0);
177                 if (optup == NULL)              /* should not fail */
178                         elog(ERROR, "cache lookup failed for operator %u", oproid);
179                 return optup;
180         }
181
182         if (!noError)
183                 ereport(ERROR,
184                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
185                         errmsg("could not identify an equality operator for type %s",
186                                    format_type_be(argtype))));
187         return NULL;
188 }
189
190 /*
191  * ordering_oper - identify a suitable sorting operator ("<") for a datatype
192  *
193  * On failure, return NULL if noError, else report a standard error
194  */
195 Operator
196 ordering_oper(Oid argtype, bool noError)
197 {
198         TypeCacheEntry *typentry;
199         Oid                     oproid;
200         Operator        optup;
201
202         /*
203          * Look for a "<" operator for the datatype.  We require it to be
204          * an exact or binary-compatible match, since most callers are not
205          * prepared to cope with adding any run-time type coercion steps.
206          *
207          * Note: the search algorithm used by typcache.c ensures that if a "<"
208          * operator is returned, it will be consistent with the "=" operator
209          * returned by equality_oper.  This is critical for sorting and grouping
210          * purposes.
211          */
212         typentry = lookup_type_cache(argtype, TYPECACHE_LT_OPR);
213         oproid = typentry->lt_opr;
214
215         /*
216          * If the datatype is an array, then we can use array_lt ... but only
217          * if there is a suitable less-than operator for the element type.
218          * (This check is not in the raw typcache.c code ... should it be?)
219          */
220         if (oproid == ARRAY_LT_OP)
221         {
222                 Oid             elem_type = get_element_type(argtype);
223
224                 if (OidIsValid(elem_type))
225                 {
226                         optup = ordering_oper(elem_type, true);
227                         if (optup != NULL)
228                                 ReleaseSysCache(optup);
229                         else
230                                 oproid = InvalidOid;    /* element type has no "<" */
231                 }
232                 else
233                         oproid = InvalidOid;            /* bogus array type? */
234         }
235
236         if (OidIsValid(oproid))
237         {
238                 optup = SearchSysCache(OPEROID,
239                                                            ObjectIdGetDatum(oproid),
240                                                            0, 0, 0);
241                 if (optup == NULL)              /* should not fail */
242                         elog(ERROR, "cache lookup failed for operator %u", oproid);
243                 return optup;
244         }
245
246         if (!noError)
247                 ereport(ERROR,
248                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
249                         errmsg("could not identify an ordering operator for type %s",
250                                    format_type_be(argtype)),
251                                  errhint("Use an explicit ordering operator or modify the query.")));
252         return NULL;
253 }
254
255 /*
256  * reverse_ordering_oper - identify DESC sort operator (">") for a datatype
257  *
258  * On failure, return NULL if noError, else report a standard error
259  */
260 Operator
261 reverse_ordering_oper(Oid argtype, bool noError)
262 {
263         TypeCacheEntry *typentry;
264         Oid                     oproid;
265         Operator        optup;
266
267         /*
268          * Look for a ">" operator for the datatype.  We require it to be
269          * an exact or binary-compatible match, since most callers are not
270          * prepared to cope with adding any run-time type coercion steps.
271          *
272          * Note: the search algorithm used by typcache.c ensures that if a ">"
273          * operator is returned, it will be consistent with the "=" operator
274          * returned by equality_oper.  This is critical for sorting and grouping
275          * purposes.
276          */
277         typentry = lookup_type_cache(argtype, TYPECACHE_GT_OPR);
278         oproid = typentry->gt_opr;
279
280         /*
281          * If the datatype is an array, then we can use array_gt ... but only
282          * if there is a suitable greater-than operator for the element type.
283          * (This check is not in the raw typcache.c code ... should it be?)
284          */
285         if (oproid == ARRAY_GT_OP)
286         {
287                 Oid             elem_type = get_element_type(argtype);
288
289                 if (OidIsValid(elem_type))
290                 {
291                         optup = reverse_ordering_oper(elem_type, true);
292                         if (optup != NULL)
293                                 ReleaseSysCache(optup);
294                         else
295                                 oproid = InvalidOid;    /* element type has no ">" */
296                 }
297                 else
298                         oproid = InvalidOid;            /* bogus array type? */
299         }
300
301         if (OidIsValid(oproid))
302         {
303                 optup = SearchSysCache(OPEROID,
304                                                            ObjectIdGetDatum(oproid),
305                                                            0, 0, 0);
306                 if (optup == NULL)              /* should not fail */
307                         elog(ERROR, "cache lookup failed for operator %u", oproid);
308                 return optup;
309         }
310
311         if (!noError)
312                 ereport(ERROR,
313                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
314                         errmsg("could not identify an ordering operator for type %s",
315                                    format_type_be(argtype)),
316                                  errhint("Use an explicit ordering operator or modify the query.")));
317         return NULL;
318 }
319
320 /*
321  * equality_oper_funcid - convenience routine for oprfuncid(equality_oper())
322  */
323 Oid
324 equality_oper_funcid(Oid argtype)
325 {
326         Operator        optup;
327         Oid                     result;
328
329         optup = equality_oper(argtype, false);
330         result = oprfuncid(optup);
331         ReleaseSysCache(optup);
332         return result;
333 }
334
335 /*
336  * ordering_oper_opid - convenience routine for oprid(ordering_oper())
337  *
338  * This was formerly called any_ordering_op()
339  */
340 Oid
341 ordering_oper_opid(Oid argtype)
342 {
343         Operator        optup;
344         Oid                     result;
345
346         optup = ordering_oper(argtype, false);
347         result = oprid(optup);
348         ReleaseSysCache(optup);
349         return result;
350 }
351
352 /*
353  * reverse_ordering_oper_opid - convenience routine for oprid(reverse_ordering_oper())
354  */
355 Oid
356 reverse_ordering_oper_opid(Oid argtype)
357 {
358         Operator        optup;
359         Oid                     result;
360
361         optup = reverse_ordering_oper(argtype, false);
362         result = oprid(optup);
363         ReleaseSysCache(optup);
364         return result;
365 }
366
367
368 /* given operator tuple, return the operator OID */
369 Oid
370 oprid(Operator op)
371 {
372         return HeapTupleGetOid(op);
373 }
374
375 /* given operator tuple, return the underlying function's OID */
376 Oid
377 oprfuncid(Operator op)
378 {
379         Form_pg_operator pgopform = (Form_pg_operator) GETSTRUCT(op);
380
381         return pgopform->oprcode;
382 }
383
384
385 /* binary_oper_exact()
386  * Check for an "exact" match to the specified operand types.
387  *
388  * If one operand is an unknown literal, assume it should be taken to be
389  * the same type as the other operand for this purpose.  Also, consider
390  * the possibility that the other operand is a domain type that needs to
391  * be reduced to its base type to find an "exact" match.
392  */
393 static Oid
394 binary_oper_exact(Oid arg1, Oid arg2,
395                                   FuncCandidateList candidates)
396 {
397         FuncCandidateList       cand;
398         bool            was_unknown = false;
399
400         /* Unspecified type for one of the arguments? then use the other */
401         if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
402         {
403                 arg1 = arg2;
404                 was_unknown = true;
405         }
406         else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
407         {
408                 arg2 = arg1;
409                 was_unknown = true;
410         }
411
412         for (cand = candidates; cand != NULL; cand = cand->next)
413         {
414                 if (arg1 == cand->args[0] && arg2 == cand->args[1])
415                         return cand->oid;
416         }
417
418         if (was_unknown)
419         {
420                 /* arg1 and arg2 are the same here, need only look at arg1 */
421                 Oid             basetype = getBaseType(arg1);
422
423                 if (basetype != arg1)
424                 {
425                         for (cand = candidates; cand != NULL; cand = cand->next)
426                         {
427                                 if (basetype == cand->args[0] && basetype == cand->args[1])
428                                         return cand->oid;
429                         }
430                 }
431         }
432
433         return InvalidOid;
434 }
435
436
437 /* oper_select_candidate()
438  *              Given the input argtype array and one or more candidates
439  *              for the operator, attempt to resolve the conflict.
440  *
441  * Returns FUNCDETAIL_NOTFOUND, FUNCDETAIL_MULTIPLE, or FUNCDETAIL_NORMAL.
442  * In the success case the Oid of the best candidate is stored in *operOid.
443  *
444  * Note that the caller has already determined that there is no candidate
445  * exactly matching the input argtype(s).  Incompatible candidates are not yet
446  * pruned away, however.
447  */
448 static FuncDetailCode
449 oper_select_candidate(int nargs,
450                                           Oid *input_typeids,
451                                           FuncCandidateList candidates,
452                                           Oid *operOid)         /* output argument */
453 {
454         int                     ncandidates;
455
456         /*
457          * Delete any candidates that cannot actually accept the given input
458          * types, whether directly or by coercion.
459          */
460         ncandidates = func_match_argtypes(nargs, input_typeids,
461                                                                           candidates, &candidates);
462
463         /* Done if no candidate or only one candidate survives */
464         if (ncandidates == 0)
465         {
466                 *operOid = InvalidOid;
467                 return FUNCDETAIL_NOTFOUND;
468         }
469         if (ncandidates == 1)
470         {
471                 *operOid = candidates->oid;
472                 return FUNCDETAIL_NORMAL;
473         }
474
475         /*
476          * Use the same heuristics as for ambiguous functions to resolve the
477          * conflict.
478          */
479         candidates = func_select_candidate(nargs, input_typeids, candidates);
480
481         if (candidates)
482         {
483                 *operOid = candidates->oid;
484                 return FUNCDETAIL_NORMAL;
485         }
486
487         *operOid = InvalidOid;
488         return FUNCDETAIL_MULTIPLE; /* failed to select a best candidate */
489 }
490
491
492 /* oper() -- search for a binary operator
493  * Given operator name, types of arg1 and arg2, return oper struct.
494  *
495  * IMPORTANT: the returned operator (if any) is only promised to be
496  * coercion-compatible with the input datatypes.  Do not use this if
497  * you need an exact- or binary-compatible match; see compatible_oper.
498  *
499  * If no matching operator found, return NULL if noError is true,
500  * raise an error if it is false.
501  *
502  * NOTE: on success, the returned object is a syscache entry.  The caller
503  * must ReleaseSysCache() the entry when done with it.
504  */
505 Operator
506 oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError)
507 {
508         FuncCandidateList clist;
509         Oid                     inputOids[2];
510         Oid                     operOid;
511         FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
512         HeapTuple       tup = NULL;
513
514         /* Get binary operators of given name */
515         clist = OpernameGetCandidates(opname, 'b');
516
517         /* No operators found? Then fail... */
518         if (clist != NULL)
519         {
520                 /*
521                  * Check for an "exact" match.
522                  */
523                 operOid = binary_oper_exact(ltypeId, rtypeId, clist);
524                 if (!OidIsValid(operOid))
525                 {
526                         /*
527                          * Otherwise, search for the most suitable candidate.
528                          */
529
530                         /*
531                          * Unspecified type for one of the arguments? then use the
532                          * other (XXX this is probably dead code?)
533                          */
534                         if (rtypeId == InvalidOid)
535                                 rtypeId = ltypeId;
536                         else if (ltypeId == InvalidOid)
537                                 ltypeId = rtypeId;
538                         inputOids[0] = ltypeId;
539                         inputOids[1] = rtypeId;
540                         fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
541                 }
542                 if (OidIsValid(operOid))
543                         tup = SearchSysCache(OPEROID,
544                                                                  ObjectIdGetDatum(operOid),
545                                                                  0, 0, 0);
546         }
547
548         if (!HeapTupleIsValid(tup) && !noError)
549                 op_error(opname, 'b', ltypeId, rtypeId, fdresult);
550
551         return (Operator) tup;
552 }
553
554 /* compatible_oper()
555  *      given an opname and input datatypes, find a compatible binary operator
556  *
557  *      This is tighter than oper() because it will not return an operator that
558  *      requires coercion of the input datatypes (but binary-compatible operators
559  *      are accepted).  Otherwise, the semantics are the same.
560  */
561 Operator
562 compatible_oper(List *op, Oid arg1, Oid arg2, bool noError)
563 {
564         Operator        optup;
565         Form_pg_operator opform;
566
567         /* oper() will find the best available match */
568         optup = oper(op, arg1, arg2, noError);
569         if (optup == (Operator) NULL)
570                 return (Operator) NULL; /* must be noError case */
571
572         /* but is it good enough? */
573         opform = (Form_pg_operator) GETSTRUCT(optup);
574         if (IsBinaryCoercible(arg1, opform->oprleft) &&
575                 IsBinaryCoercible(arg2, opform->oprright))
576                 return optup;
577
578         /* nope... */
579         ReleaseSysCache(optup);
580
581         if (!noError)
582                 ereport(ERROR,
583                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
584                                  errmsg("operator requires run-time type coercion: %s",
585                                                 op_signature_string(op, 'b', arg1, arg2))));
586
587         return (Operator) NULL;
588 }
589
590 /* compatible_oper_opid() -- get OID of a binary operator
591  *
592  * This is a convenience routine that extracts only the operator OID
593  * from the result of compatible_oper().  InvalidOid is returned if the
594  * lookup fails and noError is true.
595  */
596 Oid
597 compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
598 {
599         Operator        optup;
600         Oid                     result;
601
602         optup = compatible_oper(op, arg1, arg2, noError);
603         if (optup != NULL)
604         {
605                 result = oprid(optup);
606                 ReleaseSysCache(optup);
607                 return result;
608         }
609         return InvalidOid;
610 }
611
612
613 /* right_oper() -- search for a unary right operator (postfix operator)
614  * Given operator name and type of arg, return oper struct.
615  *
616  * IMPORTANT: the returned operator (if any) is only promised to be
617  * coercion-compatible with the input datatype.  Do not use this if
618  * you need an exact- or binary-compatible match.
619  *
620  * If no matching operator found, return NULL if noError is true,
621  * raise an error if it is false.
622  *
623  * NOTE: on success, the returned object is a syscache entry.  The caller
624  * must ReleaseSysCache() the entry when done with it.
625  */
626 Operator
627 right_oper(List *op, Oid arg, bool noError)
628 {
629         FuncCandidateList clist;
630         Oid                     operOid = InvalidOid;
631         FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
632         HeapTuple       tup = NULL;
633
634         /* Find candidates */
635         clist = OpernameGetCandidates(op, 'r');
636
637         if (clist != NULL)
638         {
639                 /*
640                  * First, quickly check to see if there is an exactly matching
641                  * operator (there can be only one such entry in the list).
642                  */
643                 FuncCandidateList clisti;
644
645                 for (clisti = clist; clisti != NULL; clisti = clisti->next)
646                 {
647                         if (arg == clisti->args[0])
648                         {
649                                 operOid = clisti->oid;
650                                 break;
651                         }
652                 }
653
654                 if (!OidIsValid(operOid))
655                 {
656                         /*
657                          * We must run oper_select_candidate even if only one
658                          * candidate, otherwise we may falsely return a
659                          * non-type-compatible operator.
660                          */
661                         fdresult = oper_select_candidate(1, &arg, clist, &operOid);
662                 }
663                 if (OidIsValid(operOid))
664                         tup = SearchSysCache(OPEROID,
665                                                                  ObjectIdGetDatum(operOid),
666                                                                  0, 0, 0);
667         }
668
669         if (!HeapTupleIsValid(tup) && !noError)
670                 op_error(op, 'r', arg, InvalidOid, fdresult);
671
672         return (Operator) tup;
673 }
674
675
676 /* left_oper() -- search for a unary left operator (prefix operator)
677  * Given operator name and type of arg, return oper struct.
678  *
679  * IMPORTANT: the returned operator (if any) is only promised to be
680  * coercion-compatible with the input datatype.  Do not use this if
681  * you need an exact- or binary-compatible match.
682  *
683  * If no matching operator found, return NULL if noError is true,
684  * raise an error if it is false.
685  *
686  * NOTE: on success, the returned object is a syscache entry.  The caller
687  * must ReleaseSysCache() the entry when done with it.
688  */
689 Operator
690 left_oper(List *op, Oid arg, bool noError)
691 {
692         FuncCandidateList clist;
693         Oid                     operOid = InvalidOid;
694         FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
695         HeapTuple       tup = NULL;
696
697         /* Find candidates */
698         clist = OpernameGetCandidates(op, 'l');
699
700         if (clist != NULL)
701         {
702                 /*
703                  * First, quickly check to see if there is an exactly matching
704                  * operator (there can be only one such entry in the list).
705                  *
706                  * The returned list has args in the form (0, oprright).  Move the
707                  * useful data into args[0] to keep oper_select_candidate simple.
708                  * XXX we are assuming here that we may scribble on the list!
709                  */
710                 FuncCandidateList clisti;
711
712                 for (clisti = clist; clisti != NULL; clisti = clisti->next)
713                 {
714                         clisti->args[0] = clisti->args[1];
715                         if (arg == clisti->args[0])
716                         {
717                                 operOid = clisti->oid;
718                                 break;
719                         }
720                 }
721
722                 if (!OidIsValid(operOid))
723                 {
724                         /*
725                          * We must run oper_select_candidate even if only one
726                          * candidate, otherwise we may falsely return a
727                          * non-type-compatible operator.
728                          */
729                         fdresult = oper_select_candidate(1, &arg, clist, &operOid);
730                 }
731                 if (OidIsValid(operOid))
732                         tup = SearchSysCache(OPEROID,
733                                                                  ObjectIdGetDatum(operOid),
734                                                                  0, 0, 0);
735         }
736
737         if (!HeapTupleIsValid(tup) && !noError)
738                 op_error(op, 'l', InvalidOid, arg, fdresult);
739
740         return (Operator) tup;
741 }
742
743 /*
744  * op_signature_string
745  *              Build a string representing an operator name, including arg type(s).
746  *              The result is something like "integer + integer".
747  *
748  * This is typically used in the construction of operator-not-found error
749  * messages.
750  */
751 static const char *
752 op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
753 {
754         StringInfoData argbuf;
755
756         initStringInfo(&argbuf);
757
758         if (oprkind != 'l')
759                 appendStringInfo(&argbuf, "%s ", format_type_be(arg1));
760
761         appendStringInfoString(&argbuf, NameListToString(op));
762
763         if (oprkind != 'r')
764                 appendStringInfo(&argbuf, " %s", format_type_be(arg2));
765
766         return argbuf.data;                     /* return palloc'd string buffer */
767 }
768
769 /*
770  * op_error - utility routine to complain about an unresolvable operator
771  */
772 static void
773 op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult)
774 {
775         if (fdresult == FUNCDETAIL_MULTIPLE)
776                 ereport(ERROR,
777                                 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
778                                  errmsg("operator is not unique: %s",
779                                                 op_signature_string(op, oprkind, arg1, arg2)),
780                                  errhint("Could not choose a best candidate operator. "
781                                                  "You may need to add explicit type casts.")));
782         else
783                 ereport(ERROR,
784                                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
785                                  errmsg("operator does not exist: %s",
786                                                 op_signature_string(op, oprkind, arg1, arg2)),
787                                  errhint("No operator matches the given name and argument type(s). "
788                                                  "You may need to add explicit type casts.")));
789 }
790
791 /*
792  * make_op()
793  *              Operator expression construction.
794  *
795  * Transform operator expression ensuring type compatibility.
796  * This is where some type conversion happens.
797  *
798  * As with coerce_type, pstate may be NULL if no special unknown-Param
799  * processing is wanted.
800  */
801 Expr *
802 make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
803 {
804         Oid                     ltypeId,
805                                 rtypeId;
806         Operator        tup;
807         Expr       *result;
808
809         /* Select the operator */
810         if (rtree == NULL)
811         {
812                 /* right operator */
813                 ltypeId = exprType(ltree);
814                 rtypeId = InvalidOid;
815                 tup = right_oper(opname, ltypeId, false);
816         }
817         else if (ltree == NULL)
818         {
819                 /* left operator */
820                 rtypeId = exprType(rtree);
821                 ltypeId = InvalidOid;
822                 tup = left_oper(opname, rtypeId, false);
823         }
824         else
825         {
826                 /* otherwise, binary operator */
827                 ltypeId = exprType(ltree);
828                 rtypeId = exprType(rtree);
829                 tup = oper(opname, ltypeId, rtypeId, false);
830         }
831
832         /* Do typecasting and build the expression tree */
833         result = make_op_expr(pstate, tup, ltree, rtree, ltypeId, rtypeId);
834
835         ReleaseSysCache(tup);
836
837         return result;
838 }
839
840 /*
841  * make_scalar_array_op()
842  *              Build expression tree for "scalar op ANY/ALL (array)" construct.
843  */
844 Expr *
845 make_scalar_array_op(ParseState *pstate, List *opname,
846                                          bool useOr,
847                                          Node *ltree, Node *rtree)
848 {
849         Oid                     ltypeId,
850                                 rtypeId,
851                                 atypeId,
852                                 res_atypeId;
853         Operator        tup;
854         Form_pg_operator opform;
855         Oid                     actual_arg_types[2];
856         Oid                     declared_arg_types[2];
857         List       *args;
858         Oid                     rettype;
859         ScalarArrayOpExpr *result;
860
861         ltypeId = exprType(ltree);
862         atypeId = exprType(rtree);
863
864         /*
865          * The right-hand input of the operator will be the element type of
866          * the array.  However, if we currently have just an untyped literal
867          * on the right, stay with that and hope we can resolve the operator.
868          */
869         if (atypeId == UNKNOWNOID)
870                 rtypeId = UNKNOWNOID;
871         else
872         {
873                 rtypeId = get_element_type(atypeId);
874                 if (!OidIsValid(rtypeId))
875                         ereport(ERROR,
876                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
877                          errmsg("op ANY/ALL (array) requires array on right side")));
878         }
879
880         /* Now resolve the operator */
881         tup = oper(opname, ltypeId, rtypeId, false);
882         opform = (Form_pg_operator) GETSTRUCT(tup);
883
884         args = makeList2(ltree, rtree);
885         actual_arg_types[0] = ltypeId;
886         actual_arg_types[1] = rtypeId;
887         declared_arg_types[0] = opform->oprleft;
888         declared_arg_types[1] = opform->oprright;
889
890         /*
891          * enforce consistency with ANYARRAY and ANYELEMENT argument and
892          * return types, possibly adjusting return type or declared_arg_types
893          * (which will be used as the cast destination by make_fn_arguments)
894          */
895         rettype = enforce_generic_type_consistency(actual_arg_types,
896                                                                                            declared_arg_types,
897                                                                                            2,
898                                                                                            opform->oprresult);
899
900         /*
901          * Check that operator result is boolean
902          */
903         if (rettype != BOOLOID)
904                 ereport(ERROR,
905                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
906                 errmsg("op ANY/ALL (array) requires operator to yield boolean")));
907         if (get_func_retset(opform->oprcode))
908                 ereport(ERROR,
909                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
910                                  errmsg("op ANY/ALL (array) requires operator not to return a set")));
911
912         /*
913          * Now switch back to the array type on the right, arranging for any
914          * needed cast to be applied.
915          */
916         res_atypeId = get_array_type(declared_arg_types[1]);
917         if (!OidIsValid(res_atypeId))
918                 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         actual_arg_types[1] = atypeId;
923         declared_arg_types[1] = res_atypeId;
924
925         /* perform the necessary typecasting of arguments */
926         make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
927
928         /* and build the expression node */
929         result = makeNode(ScalarArrayOpExpr);
930         result->opno = oprid(tup);
931         result->opfuncid = InvalidOid;
932         result->useOr = useOr;
933         result->args = args;
934
935         ReleaseSysCache(tup);
936
937         return (Expr *) result;
938 }
939
940 /*
941  * make_op_expr()
942  *              Build operator expression using an already-looked-up operator.
943  *
944  * As with coerce_type, pstate may be NULL if no special unknown-Param
945  * processing is wanted.
946  */
947 Expr *
948 make_op_expr(ParseState *pstate, Operator op,
949                          Node *ltree, Node *rtree,
950                          Oid ltypeId, Oid rtypeId)
951 {
952         Form_pg_operator opform = (Form_pg_operator) GETSTRUCT(op);
953         Oid                     actual_arg_types[2];
954         Oid                     declared_arg_types[2];
955         int                     nargs;
956         List       *args;
957         Oid                     rettype;
958         OpExpr     *result;
959
960         if (rtree == NULL)
961         {
962                 /* right operator */
963                 args = makeList1(ltree);
964                 actual_arg_types[0] = ltypeId;
965                 declared_arg_types[0] = opform->oprleft;
966                 nargs = 1;
967         }
968         else if (ltree == NULL)
969         {
970                 /* left operator */
971                 args = makeList1(rtree);
972                 actual_arg_types[0] = rtypeId;
973                 declared_arg_types[0] = opform->oprright;
974                 nargs = 1;
975         }
976         else
977         {
978                 /* otherwise, binary operator */
979                 args = makeList2(ltree, rtree);
980                 actual_arg_types[0] = ltypeId;
981                 actual_arg_types[1] = rtypeId;
982                 declared_arg_types[0] = opform->oprleft;
983                 declared_arg_types[1] = opform->oprright;
984                 nargs = 2;
985         }
986
987         /*
988          * enforce consistency with ANYARRAY and ANYELEMENT argument and
989          * return types, possibly adjusting return type or declared_arg_types
990          * (which will be used as the cast destination by make_fn_arguments)
991          */
992         rettype = enforce_generic_type_consistency(actual_arg_types,
993                                                                                            declared_arg_types,
994                                                                                            nargs,
995                                                                                            opform->oprresult);
996
997         /* perform the necessary typecasting of arguments */
998         make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
999
1000         /* and build the expression node */
1001         result = makeNode(OpExpr);
1002         result->opno = oprid(op);
1003         result->opfuncid = InvalidOid;
1004         result->opresulttype = rettype;
1005         result->opretset = get_func_retset(opform->oprcode);
1006         result->args = args;
1007
1008         return (Expr *) result;
1009 }