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

Generated by: LCOV version 1.14