LCOV - code coverage report
Current view: top level - src/backend/parser - parse_oper.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 93.1 % 290 270
Test Date: 2026-04-05 20:17:51 Functions: 95.0 % 20 19
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.0-1