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

Generated by: LCOV version 1.14