Header And Logo

PostgreSQL
| The world's most advanced open source database.

parse_oper.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * parse_oper.c
00004  *      handle operator things for parser
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/parser/parse_oper.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 
00016 #include "postgres.h"
00017 
00018 #include "access/htup_details.h"
00019 #include "catalog/pg_operator.h"
00020 #include "catalog/pg_type.h"
00021 #include "lib/stringinfo.h"
00022 #include "nodes/nodeFuncs.h"
00023 #include "parser/parse_coerce.h"
00024 #include "parser/parse_func.h"
00025 #include "parser/parse_oper.h"
00026 #include "parser/parse_type.h"
00027 #include "utils/builtins.h"
00028 #include "utils/inval.h"
00029 #include "utils/lsyscache.h"
00030 #include "utils/syscache.h"
00031 #include "utils/typcache.h"
00032 
00033 
00034 /*
00035  * The lookup key for the operator lookaside hash table.  Unused bits must be
00036  * zeroes to ensure hashing works consistently --- in particular, oprname
00037  * must be zero-padded and any unused entries in search_path must be zero.
00038  *
00039  * search_path contains the actual search_path with which the entry was
00040  * derived (minus temp namespace if any), or else the single specified
00041  * schema OID if we are looking up an explicitly-qualified operator name.
00042  *
00043  * search_path has to be fixed-length since the hashtable code insists on
00044  * fixed-size keys.  If your search path is longer than that, we just punt
00045  * and don't cache anything.
00046  */
00047 
00048 /* If your search_path is longer than this, sucks to be you ... */
00049 #define MAX_CACHED_PATH_LEN     16
00050 
00051 typedef struct OprCacheKey
00052 {
00053     char        oprname[NAMEDATALEN];
00054     Oid         left_arg;       /* Left input OID, or 0 if prefix op */
00055     Oid         right_arg;      /* Right input OID, or 0 if postfix op */
00056     Oid         search_path[MAX_CACHED_PATH_LEN];
00057 } OprCacheKey;
00058 
00059 typedef struct OprCacheEntry
00060 {
00061     /* the hash lookup key MUST BE FIRST */
00062     OprCacheKey key;
00063 
00064     Oid         opr_oid;        /* OID of the resolved operator */
00065 } OprCacheEntry;
00066 
00067 
00068 static Oid  binary_oper_exact(List *opname, Oid arg1, Oid arg2);
00069 static FuncDetailCode oper_select_candidate(int nargs,
00070                       Oid *input_typeids,
00071                       FuncCandidateList candidates,
00072                       Oid *operOid);
00073 static const char *op_signature_string(List *op, char oprkind,
00074                     Oid arg1, Oid arg2);
00075 static void op_error(ParseState *pstate, List *op, char oprkind,
00076          Oid arg1, Oid arg2,
00077          FuncDetailCode fdresult, int location);
00078 static bool make_oper_cache_key(OprCacheKey *key, List *opname,
00079                     Oid ltypeId, Oid rtypeId);
00080 static Oid  find_oper_cache_entry(OprCacheKey *key);
00081 static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid);
00082 static void InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue);
00083 
00084 
00085 /*
00086  * LookupOperName
00087  *      Given a possibly-qualified operator name and exact input datatypes,
00088  *      look up the operator.
00089  *
00090  * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for
00091  * a postfix op.
00092  *
00093  * If the operator name is not schema-qualified, it is sought in the current
00094  * namespace search path.
00095  *
00096  * If the operator is not found, we return InvalidOid if noError is true,
00097  * else raise an error.  pstate and location are used only to report the
00098  * error position; pass NULL/-1 if not available.
00099  */
00100 Oid
00101 LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
00102                bool noError, int location)
00103 {
00104     Oid         result;
00105 
00106     result = OpernameGetOprid(opername, oprleft, oprright);
00107     if (OidIsValid(result))
00108         return result;
00109 
00110     /* we don't use op_error here because only an exact match is wanted */
00111     if (!noError)
00112     {
00113         char        oprkind;
00114 
00115         if (!OidIsValid(oprleft))
00116             oprkind = 'l';
00117         else if (!OidIsValid(oprright))
00118             oprkind = 'r';
00119         else
00120             oprkind = 'b';
00121 
00122         ereport(ERROR,
00123                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00124                  errmsg("operator does not exist: %s",
00125                         op_signature_string(opername, oprkind,
00126                                             oprleft, oprright)),
00127                  parser_errposition(pstate, location)));
00128     }
00129 
00130     return InvalidOid;
00131 }
00132 
00133 /*
00134  * LookupOperNameTypeNames
00135  *      Like LookupOperName, but the argument types are specified by
00136  *      TypeName nodes.
00137  *
00138  * Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op.
00139  */
00140 Oid
00141 LookupOperNameTypeNames(ParseState *pstate, List *opername,
00142                         TypeName *oprleft, TypeName *oprright,
00143                         bool noError, int location)
00144 {
00145     Oid         leftoid,
00146                 rightoid;
00147 
00148     if (oprleft == NULL)
00149         leftoid = InvalidOid;
00150     else
00151         leftoid = typenameTypeId(pstate, oprleft);
00152 
00153     if (oprright == NULL)
00154         rightoid = InvalidOid;
00155     else
00156         rightoid = typenameTypeId(pstate, oprright);
00157 
00158     return LookupOperName(pstate, opername, leftoid, rightoid,
00159                           noError, location);
00160 }
00161 
00162 /*
00163  * get_sort_group_operators - get default sorting/grouping operators for type
00164  *
00165  * We fetch the "<", "=", and ">" operators all at once to reduce lookup
00166  * overhead (knowing that most callers will be interested in at least two).
00167  * However, a given datatype might have only an "=" operator, if it is
00168  * hashable but not sortable.  (Other combinations of present and missing
00169  * operators shouldn't happen, unless the system catalogs are messed up.)
00170  *
00171  * If an operator is missing and the corresponding needXX flag is true,
00172  * throw a standard error message, else return InvalidOid.
00173  *
00174  * In addition to the operator OIDs themselves, this function can identify
00175  * whether the "=" operator is hashable.
00176  *
00177  * Callers can pass NULL pointers for any results they don't care to get.
00178  *
00179  * Note: the results are guaranteed to be exact or binary-compatible matches,
00180  * since most callers are not prepared to cope with adding any run-time type
00181  * coercion steps.
00182  */
00183 void
00184 get_sort_group_operators(Oid argtype,
00185                          bool needLT, bool needEQ, bool needGT,
00186                          Oid *ltOpr, Oid *eqOpr, Oid *gtOpr,
00187                          bool *isHashable)
00188 {
00189     TypeCacheEntry *typentry;
00190     int         cache_flags;
00191     Oid         lt_opr;
00192     Oid         eq_opr;
00193     Oid         gt_opr;
00194     bool        hashable;
00195 
00196     /*
00197      * Look up the operators using the type cache.
00198      *
00199      * Note: the search algorithm used by typcache.c ensures that the results
00200      * are consistent, ie all from matching opclasses.
00201      */
00202     if (isHashable != NULL)
00203         cache_flags = TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR |
00204             TYPECACHE_HASH_PROC;
00205     else
00206         cache_flags = TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR | TYPECACHE_GT_OPR;
00207 
00208     typentry = lookup_type_cache(argtype, cache_flags);
00209     lt_opr = typentry->lt_opr;
00210     eq_opr = typentry->eq_opr;
00211     gt_opr = typentry->gt_opr;
00212     hashable = OidIsValid(typentry->hash_proc);
00213 
00214     /* Report errors if needed */
00215     if ((needLT && !OidIsValid(lt_opr)) ||
00216         (needGT && !OidIsValid(gt_opr)))
00217         ereport(ERROR,
00218                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00219                  errmsg("could not identify an ordering operator for type %s",
00220                         format_type_be(argtype)),
00221          errhint("Use an explicit ordering operator or modify the query.")));
00222     if (needEQ && !OidIsValid(eq_opr))
00223         ereport(ERROR,
00224                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00225                  errmsg("could not identify an equality operator for type %s",
00226                         format_type_be(argtype))));
00227 
00228     /* Return results as needed */
00229     if (ltOpr)
00230         *ltOpr = lt_opr;
00231     if (eqOpr)
00232         *eqOpr = eq_opr;
00233     if (gtOpr)
00234         *gtOpr = gt_opr;
00235     if (isHashable)
00236         *isHashable = hashable;
00237 }
00238 
00239 
00240 /* given operator tuple, return the operator OID */
00241 Oid
00242 oprid(Operator op)
00243 {
00244     return HeapTupleGetOid(op);
00245 }
00246 
00247 /* given operator tuple, return the underlying function's OID */
00248 Oid
00249 oprfuncid(Operator op)
00250 {
00251     Form_pg_operator pgopform = (Form_pg_operator) GETSTRUCT(op);
00252 
00253     return pgopform->oprcode;
00254 }
00255 
00256 
00257 /* binary_oper_exact()
00258  * Check for an "exact" match to the specified operand types.
00259  *
00260  * If one operand is an unknown literal, assume it should be taken to be
00261  * the same type as the other operand for this purpose.  Also, consider
00262  * the possibility that the other operand is a domain type that needs to
00263  * be reduced to its base type to find an "exact" match.
00264  */
00265 static Oid
00266 binary_oper_exact(List *opname, Oid arg1, Oid arg2)
00267 {
00268     Oid         result;
00269     bool        was_unknown = false;
00270 
00271     /* Unspecified type for one of the arguments? then use the other */
00272     if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
00273     {
00274         arg1 = arg2;
00275         was_unknown = true;
00276     }
00277     else if ((arg2 == UNKNOWNOID) && (arg1 != InvalidOid))
00278     {
00279         arg2 = arg1;
00280         was_unknown = true;
00281     }
00282 
00283     result = OpernameGetOprid(opname, arg1, arg2);
00284     if (OidIsValid(result))
00285         return result;
00286 
00287     if (was_unknown)
00288     {
00289         /* arg1 and arg2 are the same here, need only look at arg1 */
00290         Oid         basetype = getBaseType(arg1);
00291 
00292         if (basetype != arg1)
00293         {
00294             result = OpernameGetOprid(opname, basetype, basetype);
00295             if (OidIsValid(result))
00296                 return result;
00297         }
00298     }
00299 
00300     return InvalidOid;
00301 }
00302 
00303 
00304 /* oper_select_candidate()
00305  *      Given the input argtype array and one or more candidates
00306  *      for the operator, attempt to resolve the conflict.
00307  *
00308  * Returns FUNCDETAIL_NOTFOUND, FUNCDETAIL_MULTIPLE, or FUNCDETAIL_NORMAL.
00309  * In the success case the Oid of the best candidate is stored in *operOid.
00310  *
00311  * Note that the caller has already determined that there is no candidate
00312  * exactly matching the input argtype(s).  Incompatible candidates are not yet
00313  * pruned away, however.
00314  */
00315 static FuncDetailCode
00316 oper_select_candidate(int nargs,
00317                       Oid *input_typeids,
00318                       FuncCandidateList candidates,
00319                       Oid *operOid)     /* output argument */
00320 {
00321     int         ncandidates;
00322 
00323     /*
00324      * Delete any candidates that cannot actually accept the given input
00325      * types, whether directly or by coercion.
00326      */
00327     ncandidates = func_match_argtypes(nargs, input_typeids,
00328                                       candidates, &candidates);
00329 
00330     /* Done if no candidate or only one candidate survives */
00331     if (ncandidates == 0)
00332     {
00333         *operOid = InvalidOid;
00334         return FUNCDETAIL_NOTFOUND;
00335     }
00336     if (ncandidates == 1)
00337     {
00338         *operOid = candidates->oid;
00339         return FUNCDETAIL_NORMAL;
00340     }
00341 
00342     /*
00343      * Use the same heuristics as for ambiguous functions to resolve the
00344      * conflict.
00345      */
00346     candidates = func_select_candidate(nargs, input_typeids, candidates);
00347 
00348     if (candidates)
00349     {
00350         *operOid = candidates->oid;
00351         return FUNCDETAIL_NORMAL;
00352     }
00353 
00354     *operOid = InvalidOid;
00355     return FUNCDETAIL_MULTIPLE; /* failed to select a best candidate */
00356 }
00357 
00358 
00359 /* oper() -- search for a binary operator
00360  * Given operator name, types of arg1 and arg2, return oper struct.
00361  *
00362  * IMPORTANT: the returned operator (if any) is only promised to be
00363  * coercion-compatible with the input datatypes.  Do not use this if
00364  * you need an exact- or binary-compatible match; see compatible_oper.
00365  *
00366  * If no matching operator found, return NULL if noError is true,
00367  * raise an error if it is false.  pstate and location are used only to report
00368  * the error position; pass NULL/-1 if not available.
00369  *
00370  * NOTE: on success, the returned object is a syscache entry.  The caller
00371  * must ReleaseSysCache() the entry when done with it.
00372  */
00373 Operator
00374 oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId,
00375      bool noError, int location)
00376 {
00377     Oid         operOid;
00378     OprCacheKey key;
00379     bool        key_ok;
00380     FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
00381     HeapTuple   tup = NULL;
00382 
00383     /*
00384      * Try to find the mapping in the lookaside cache.
00385      */
00386     key_ok = make_oper_cache_key(&key, opname, ltypeId, rtypeId);
00387     if (key_ok)
00388     {
00389         operOid = find_oper_cache_entry(&key);
00390         if (OidIsValid(operOid))
00391         {
00392             tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
00393             if (HeapTupleIsValid(tup))
00394                 return (Operator) tup;
00395         }
00396     }
00397 
00398     /*
00399      * First try for an "exact" match.
00400      */
00401     operOid = binary_oper_exact(opname, ltypeId, rtypeId);
00402     if (!OidIsValid(operOid))
00403     {
00404         /*
00405          * Otherwise, search for the most suitable candidate.
00406          */
00407         FuncCandidateList clist;
00408 
00409         /* Get binary operators of given name */
00410         clist = OpernameGetCandidates(opname, 'b');
00411 
00412         /* No operators found? Then fail... */
00413         if (clist != NULL)
00414         {
00415             /*
00416              * Unspecified type for one of the arguments? then use the other
00417              * (XXX this is probably dead code?)
00418              */
00419             Oid         inputOids[2];
00420 
00421             if (rtypeId == InvalidOid)
00422                 rtypeId = ltypeId;
00423             else if (ltypeId == InvalidOid)
00424                 ltypeId = rtypeId;
00425             inputOids[0] = ltypeId;
00426             inputOids[1] = rtypeId;
00427             fdresult = oper_select_candidate(2, inputOids, clist, &operOid);
00428         }
00429     }
00430 
00431     if (OidIsValid(operOid))
00432         tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
00433 
00434     if (HeapTupleIsValid(tup))
00435     {
00436         if (key_ok)
00437             make_oper_cache_entry(&key, operOid);
00438     }
00439     else if (!noError)
00440         op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location);
00441 
00442     return (Operator) tup;
00443 }
00444 
00445 /* compatible_oper()
00446  *  given an opname and input datatypes, find a compatible binary operator
00447  *
00448  *  This is tighter than oper() because it will not return an operator that
00449  *  requires coercion of the input datatypes (but binary-compatible operators
00450  *  are accepted).  Otherwise, the semantics are the same.
00451  */
00452 Operator
00453 compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2,
00454                 bool noError, int location)
00455 {
00456     Operator    optup;
00457     Form_pg_operator opform;
00458 
00459     /* oper() will find the best available match */
00460     optup = oper(pstate, op, arg1, arg2, noError, location);
00461     if (optup == (Operator) NULL)
00462         return (Operator) NULL; /* must be noError case */
00463 
00464     /* but is it good enough? */
00465     opform = (Form_pg_operator) GETSTRUCT(optup);
00466     if (IsBinaryCoercible(arg1, opform->oprleft) &&
00467         IsBinaryCoercible(arg2, opform->oprright))
00468         return optup;
00469 
00470     /* nope... */
00471     ReleaseSysCache(optup);
00472 
00473     if (!noError)
00474         ereport(ERROR,
00475                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00476                  errmsg("operator requires run-time type coercion: %s",
00477                         op_signature_string(op, 'b', arg1, arg2)),
00478                  parser_errposition(pstate, location)));
00479 
00480     return (Operator) NULL;
00481 }
00482 
00483 /* compatible_oper_opid() -- get OID of a binary operator
00484  *
00485  * This is a convenience routine that extracts only the operator OID
00486  * from the result of compatible_oper().  InvalidOid is returned if the
00487  * lookup fails and noError is true.
00488  */
00489 Oid
00490 compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
00491 {
00492     Operator    optup;
00493     Oid         result;
00494 
00495     optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
00496     if (optup != NULL)
00497     {
00498         result = oprid(optup);
00499         ReleaseSysCache(optup);
00500         return result;
00501     }
00502     return InvalidOid;
00503 }
00504 
00505 
00506 /* right_oper() -- search for a unary right operator (postfix operator)
00507  * Given operator name and type of arg, return oper struct.
00508  *
00509  * IMPORTANT: the returned operator (if any) is only promised to be
00510  * coercion-compatible with the input datatype.  Do not use this if
00511  * you need an exact- or binary-compatible match.
00512  *
00513  * If no matching operator found, return NULL if noError is true,
00514  * raise an error if it is false.  pstate and location are used only to report
00515  * the error position; pass NULL/-1 if not available.
00516  *
00517  * NOTE: on success, the returned object is a syscache entry.  The caller
00518  * must ReleaseSysCache() the entry when done with it.
00519  */
00520 Operator
00521 right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
00522 {
00523     Oid         operOid;
00524     OprCacheKey key;
00525     bool        key_ok;
00526     FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
00527     HeapTuple   tup = NULL;
00528 
00529     /*
00530      * Try to find the mapping in the lookaside cache.
00531      */
00532     key_ok = make_oper_cache_key(&key, op, arg, InvalidOid);
00533     if (key_ok)
00534     {
00535         operOid = find_oper_cache_entry(&key);
00536         if (OidIsValid(operOid))
00537         {
00538             tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
00539             if (HeapTupleIsValid(tup))
00540                 return (Operator) tup;
00541         }
00542     }
00543 
00544     /*
00545      * First try for an "exact" match.
00546      */
00547     operOid = OpernameGetOprid(op, arg, InvalidOid);
00548     if (!OidIsValid(operOid))
00549     {
00550         /*
00551          * Otherwise, search for the most suitable candidate.
00552          */
00553         FuncCandidateList clist;
00554 
00555         /* Get postfix operators of given name */
00556         clist = OpernameGetCandidates(op, 'r');
00557 
00558         /* No operators found? Then fail... */
00559         if (clist != NULL)
00560         {
00561             /*
00562              * We must run oper_select_candidate even if only one candidate,
00563              * otherwise we may falsely return a non-type-compatible operator.
00564              */
00565             fdresult = oper_select_candidate(1, &arg, clist, &operOid);
00566         }
00567     }
00568 
00569     if (OidIsValid(operOid))
00570         tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
00571 
00572     if (HeapTupleIsValid(tup))
00573     {
00574         if (key_ok)
00575             make_oper_cache_entry(&key, operOid);
00576     }
00577     else if (!noError)
00578         op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location);
00579 
00580     return (Operator) tup;
00581 }
00582 
00583 
00584 /* left_oper() -- search for a unary left operator (prefix operator)
00585  * Given operator name and type of arg, return oper struct.
00586  *
00587  * IMPORTANT: the returned operator (if any) is only promised to be
00588  * coercion-compatible with the input datatype.  Do not use this if
00589  * you need an exact- or binary-compatible match.
00590  *
00591  * If no matching operator found, return NULL if noError is true,
00592  * raise an error if it is false.  pstate and location are used only to report
00593  * the error position; pass NULL/-1 if not available.
00594  *
00595  * NOTE: on success, the returned object is a syscache entry.  The caller
00596  * must ReleaseSysCache() the entry when done with it.
00597  */
00598 Operator
00599 left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
00600 {
00601     Oid         operOid;
00602     OprCacheKey key;
00603     bool        key_ok;
00604     FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND;
00605     HeapTuple   tup = NULL;
00606 
00607     /*
00608      * Try to find the mapping in the lookaside cache.
00609      */
00610     key_ok = make_oper_cache_key(&key, op, InvalidOid, arg);
00611     if (key_ok)
00612     {
00613         operOid = find_oper_cache_entry(&key);
00614         if (OidIsValid(operOid))
00615         {
00616             tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
00617             if (HeapTupleIsValid(tup))
00618                 return (Operator) tup;
00619         }
00620     }
00621 
00622     /*
00623      * First try for an "exact" match.
00624      */
00625     operOid = OpernameGetOprid(op, InvalidOid, arg);
00626     if (!OidIsValid(operOid))
00627     {
00628         /*
00629          * Otherwise, search for the most suitable candidate.
00630          */
00631         FuncCandidateList clist;
00632 
00633         /* Get prefix operators of given name */
00634         clist = OpernameGetCandidates(op, 'l');
00635 
00636         /* No operators found? Then fail... */
00637         if (clist != NULL)
00638         {
00639             /*
00640              * The returned list has args in the form (0, oprright). Move the
00641              * useful data into args[0] to keep oper_select_candidate simple.
00642              * XXX we are assuming here that we may scribble on the list!
00643              */
00644             FuncCandidateList clisti;
00645 
00646             for (clisti = clist; clisti != NULL; clisti = clisti->next)
00647             {
00648                 clisti->args[0] = clisti->args[1];
00649             }
00650 
00651             /*
00652              * We must run oper_select_candidate even if only one candidate,
00653              * otherwise we may falsely return a non-type-compatible operator.
00654              */
00655             fdresult = oper_select_candidate(1, &arg, clist, &operOid);
00656         }
00657     }
00658 
00659     if (OidIsValid(operOid))
00660         tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
00661 
00662     if (HeapTupleIsValid(tup))
00663     {
00664         if (key_ok)
00665             make_oper_cache_entry(&key, operOid);
00666     }
00667     else if (!noError)
00668         op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location);
00669 
00670     return (Operator) tup;
00671 }
00672 
00673 /*
00674  * op_signature_string
00675  *      Build a string representing an operator name, including arg type(s).
00676  *      The result is something like "integer + integer".
00677  *
00678  * This is typically used in the construction of operator-not-found error
00679  * messages.
00680  */
00681 static const char *
00682 op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
00683 {
00684     StringInfoData argbuf;
00685 
00686     initStringInfo(&argbuf);
00687 
00688     if (oprkind != 'l')
00689         appendStringInfo(&argbuf, "%s ", format_type_be(arg1));
00690 
00691     appendStringInfoString(&argbuf, NameListToString(op));
00692 
00693     if (oprkind != 'r')
00694         appendStringInfo(&argbuf, " %s", format_type_be(arg2));
00695 
00696     return argbuf.data;         /* return palloc'd string buffer */
00697 }
00698 
00699 /*
00700  * op_error - utility routine to complain about an unresolvable operator
00701  */
00702 static void
00703 op_error(ParseState *pstate, List *op, char oprkind,
00704          Oid arg1, Oid arg2,
00705          FuncDetailCode fdresult, int location)
00706 {
00707     if (fdresult == FUNCDETAIL_MULTIPLE)
00708         ereport(ERROR,
00709                 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
00710                  errmsg("operator is not unique: %s",
00711                         op_signature_string(op, oprkind, arg1, arg2)),
00712                  errhint("Could not choose a best candidate operator. "
00713                          "You might need to add explicit type casts."),
00714                  parser_errposition(pstate, location)));
00715     else
00716         ereport(ERROR,
00717                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00718                  errmsg("operator does not exist: %s",
00719                         op_signature_string(op, oprkind, arg1, arg2)),
00720           errhint("No operator matches the given name and argument type(s). "
00721                   "You might need to add explicit type casts."),
00722                  parser_errposition(pstate, location)));
00723 }
00724 
00725 /*
00726  * make_op()
00727  *      Operator expression construction.
00728  *
00729  * Transform operator expression ensuring type compatibility.
00730  * This is where some type conversion happens.
00731  *
00732  * As with coerce_type, pstate may be NULL if no special unknown-Param
00733  * processing is wanted.
00734  */
00735 Expr *
00736 make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
00737         int location)
00738 {
00739     Oid         ltypeId,
00740                 rtypeId;
00741     Operator    tup;
00742     Form_pg_operator opform;
00743     Oid         actual_arg_types[2];
00744     Oid         declared_arg_types[2];
00745     int         nargs;
00746     List       *args;
00747     Oid         rettype;
00748     OpExpr     *result;
00749 
00750     /* Select the operator */
00751     if (rtree == NULL)
00752     {
00753         /* right operator */
00754         ltypeId = exprType(ltree);
00755         rtypeId = InvalidOid;
00756         tup = right_oper(pstate, opname, ltypeId, false, location);
00757     }
00758     else if (ltree == NULL)
00759     {
00760         /* left operator */
00761         rtypeId = exprType(rtree);
00762         ltypeId = InvalidOid;
00763         tup = left_oper(pstate, opname, rtypeId, false, location);
00764     }
00765     else
00766     {
00767         /* otherwise, binary operator */
00768         ltypeId = exprType(ltree);
00769         rtypeId = exprType(rtree);
00770         tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
00771     }
00772 
00773     opform = (Form_pg_operator) GETSTRUCT(tup);
00774 
00775     /* Check it's not a shell */
00776     if (!RegProcedureIsValid(opform->oprcode))
00777         ereport(ERROR,
00778                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00779                  errmsg("operator is only a shell: %s",
00780                         op_signature_string(opname,
00781                                             opform->oprkind,
00782                                             opform->oprleft,
00783                                             opform->oprright)),
00784                  parser_errposition(pstate, location)));
00785 
00786     /* Do typecasting and build the expression tree */
00787     if (rtree == NULL)
00788     {
00789         /* right operator */
00790         args = list_make1(ltree);
00791         actual_arg_types[0] = ltypeId;
00792         declared_arg_types[0] = opform->oprleft;
00793         nargs = 1;
00794     }
00795     else if (ltree == NULL)
00796     {
00797         /* left operator */
00798         args = list_make1(rtree);
00799         actual_arg_types[0] = rtypeId;
00800         declared_arg_types[0] = opform->oprright;
00801         nargs = 1;
00802     }
00803     else
00804     {
00805         /* otherwise, binary operator */
00806         args = list_make2(ltree, rtree);
00807         actual_arg_types[0] = ltypeId;
00808         actual_arg_types[1] = rtypeId;
00809         declared_arg_types[0] = opform->oprleft;
00810         declared_arg_types[1] = opform->oprright;
00811         nargs = 2;
00812     }
00813 
00814     /*
00815      * enforce consistency with polymorphic argument and return types,
00816      * possibly adjusting return type or declared_arg_types (which will be
00817      * used as the cast destination by make_fn_arguments)
00818      */
00819     rettype = enforce_generic_type_consistency(actual_arg_types,
00820                                                declared_arg_types,
00821                                                nargs,
00822                                                opform->oprresult,
00823                                                false);
00824 
00825     /* perform the necessary typecasting of arguments */
00826     make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
00827 
00828     /* and build the expression node */
00829     result = makeNode(OpExpr);
00830     result->opno = oprid(tup);
00831     result->opfuncid = opform->oprcode;
00832     result->opresulttype = rettype;
00833     result->opretset = get_func_retset(opform->oprcode);
00834     /* opcollid and inputcollid will be set by parse_collate.c */
00835     result->args = args;
00836     result->location = location;
00837 
00838     ReleaseSysCache(tup);
00839 
00840     return (Expr *) result;
00841 }
00842 
00843 /*
00844  * make_scalar_array_op()
00845  *      Build expression tree for "scalar op ANY/ALL (array)" construct.
00846  */
00847 Expr *
00848 make_scalar_array_op(ParseState *pstate, List *opname,
00849                      bool useOr,
00850                      Node *ltree, Node *rtree,
00851                      int location)
00852 {
00853     Oid         ltypeId,
00854                 rtypeId,
00855                 atypeId,
00856                 res_atypeId;
00857     Operator    tup;
00858     Form_pg_operator opform;
00859     Oid         actual_arg_types[2];
00860     Oid         declared_arg_types[2];
00861     List       *args;
00862     Oid         rettype;
00863     ScalarArrayOpExpr *result;
00864 
00865     ltypeId = exprType(ltree);
00866     atypeId = exprType(rtree);
00867 
00868     /*
00869      * The right-hand input of the operator will be the element type of the
00870      * array.  However, if we currently have just an untyped literal on the
00871      * right, stay with that and hope we can resolve the operator.
00872      */
00873     if (atypeId == UNKNOWNOID)
00874         rtypeId = UNKNOWNOID;
00875     else
00876     {
00877         rtypeId = get_base_element_type(atypeId);
00878         if (!OidIsValid(rtypeId))
00879             ereport(ERROR,
00880                     (errcode(ERRCODE_WRONG_OBJECT_TYPE),
00881                    errmsg("op ANY/ALL (array) requires array on right side"),
00882                      parser_errposition(pstate, location)));
00883     }
00884 
00885     /* Now resolve the operator */
00886     tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
00887     opform = (Form_pg_operator) GETSTRUCT(tup);
00888 
00889     /* Check it's not a shell */
00890     if (!RegProcedureIsValid(opform->oprcode))
00891         ereport(ERROR,
00892                 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00893                  errmsg("operator is only a shell: %s",
00894                         op_signature_string(opname,
00895                                             opform->oprkind,
00896                                             opform->oprleft,
00897                                             opform->oprright)),
00898                  parser_errposition(pstate, location)));
00899 
00900     args = list_make2(ltree, rtree);
00901     actual_arg_types[0] = ltypeId;
00902     actual_arg_types[1] = rtypeId;
00903     declared_arg_types[0] = opform->oprleft;
00904     declared_arg_types[1] = opform->oprright;
00905 
00906     /*
00907      * enforce consistency with polymorphic argument and return types,
00908      * possibly adjusting return type or declared_arg_types (which will be
00909      * used as the cast destination by make_fn_arguments)
00910      */
00911     rettype = enforce_generic_type_consistency(actual_arg_types,
00912                                                declared_arg_types,
00913                                                2,
00914                                                opform->oprresult,
00915                                                false);
00916 
00917     /*
00918      * Check that operator result is boolean
00919      */
00920     if (rettype != BOOLOID)
00921         ereport(ERROR,
00922                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
00923              errmsg("op ANY/ALL (array) requires operator to yield boolean"),
00924                  parser_errposition(pstate, location)));
00925     if (get_func_retset(opform->oprcode))
00926         ereport(ERROR,
00927                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
00928           errmsg("op ANY/ALL (array) requires operator not to return a set"),
00929                  parser_errposition(pstate, location)));
00930 
00931     /*
00932      * Now switch back to the array type on the right, arranging for any
00933      * needed cast to be applied.  Beware of polymorphic operators here;
00934      * enforce_generic_type_consistency may or may not have replaced a
00935      * polymorphic type with a real one.
00936      */
00937     if (IsPolymorphicType(declared_arg_types[1]))
00938     {
00939         /* assume the actual array type is OK */
00940         res_atypeId = atypeId;
00941     }
00942     else
00943     {
00944         res_atypeId = get_array_type(declared_arg_types[1]);
00945         if (!OidIsValid(res_atypeId))
00946             ereport(ERROR,
00947                     (errcode(ERRCODE_UNDEFINED_OBJECT),
00948                      errmsg("could not find array type for data type %s",
00949                             format_type_be(declared_arg_types[1])),
00950                      parser_errposition(pstate, location)));
00951     }
00952     actual_arg_types[1] = atypeId;
00953     declared_arg_types[1] = res_atypeId;
00954 
00955     /* perform the necessary typecasting of arguments */
00956     make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types);
00957 
00958     /* and build the expression node */
00959     result = makeNode(ScalarArrayOpExpr);
00960     result->opno = oprid(tup);
00961     result->opfuncid = opform->oprcode;
00962     result->useOr = useOr;
00963     /* inputcollid will be set by parse_collate.c */
00964     result->args = args;
00965     result->location = location;
00966 
00967     ReleaseSysCache(tup);
00968 
00969     return (Expr *) result;
00970 }
00971 
00972 
00973 /*
00974  * Lookaside cache to speed operator lookup.  Possibly this should be in
00975  * a separate module under utils/cache/ ?
00976  *
00977  * The idea here is that the mapping from operator name and given argument
00978  * types is constant for a given search path (or single specified schema OID)
00979  * so long as the contents of pg_operator and pg_cast don't change.  And that
00980  * mapping is pretty expensive to compute, especially for ambiguous operators;
00981  * this is mainly because there are a *lot* of instances of popular operator
00982  * names such as "=", and we have to check each one to see which is the
00983  * best match.  So once we have identified the correct mapping, we save it
00984  * in a cache that need only be flushed on pg_operator or pg_cast change.
00985  * (pg_cast must be considered because changes in the set of implicit casts
00986  * affect the set of applicable operators for any given input datatype.)
00987  *
00988  * XXX in principle, ALTER TABLE ... INHERIT could affect the mapping as
00989  * well, but we disregard that since there's no convenient way to find out
00990  * about it, and it seems a pretty far-fetched corner-case anyway.
00991  *
00992  * Note: at some point it might be worth doing a similar cache for function
00993  * lookups.  However, the potential gain is a lot less since (a) function
00994  * names are generally not overloaded as heavily as operator names, and
00995  * (b) we'd have to flush on pg_proc updates, which are probably a good
00996  * deal more common than pg_operator updates.
00997  */
00998 
00999 /* The operator cache hashtable */
01000 static HTAB *OprCacheHash = NULL;
01001 
01002 
01003 /*
01004  * make_oper_cache_key
01005  *      Fill the lookup key struct given operator name and arg types.
01006  *
01007  * Returns TRUE if successful, FALSE if the search_path overflowed
01008  * (hence no caching is possible).
01009  */
01010 static bool
01011 make_oper_cache_key(OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId)
01012 {
01013     char       *schemaname;
01014     char       *opername;
01015 
01016     /* deconstruct the name list */
01017     DeconstructQualifiedName(opname, &schemaname, &opername);
01018 
01019     /* ensure zero-fill for stable hashing */
01020     MemSet(key, 0, sizeof(OprCacheKey));
01021 
01022     /* save operator name and input types into key */
01023     strlcpy(key->oprname, opername, NAMEDATALEN);
01024     key->left_arg = ltypeId;
01025     key->right_arg = rtypeId;
01026 
01027     if (schemaname)
01028     {
01029         /* search only in exact schema given */
01030         key->search_path[0] = LookupExplicitNamespace(schemaname, false);
01031     }
01032     else
01033     {
01034         /* get the active search path */
01035         if (fetch_search_path_array(key->search_path,
01036                                   MAX_CACHED_PATH_LEN) > MAX_CACHED_PATH_LEN)
01037             return false;       /* oops, didn't fit */
01038     }
01039 
01040     return true;
01041 }
01042 
01043 /*
01044  * find_oper_cache_entry
01045  *
01046  * Look for a cache entry matching the given key.  If found, return the
01047  * contained operator OID, else return InvalidOid.
01048  */
01049 static Oid
01050 find_oper_cache_entry(OprCacheKey *key)
01051 {
01052     OprCacheEntry *oprentry;
01053 
01054     if (OprCacheHash == NULL)
01055     {
01056         /* First time through: initialize the hash table */
01057         HASHCTL     ctl;
01058 
01059         MemSet(&ctl, 0, sizeof(ctl));
01060         ctl.keysize = sizeof(OprCacheKey);
01061         ctl.entrysize = sizeof(OprCacheEntry);
01062         ctl.hash = tag_hash;
01063         OprCacheHash = hash_create("Operator lookup cache", 256,
01064                                    &ctl, HASH_ELEM | HASH_FUNCTION);
01065 
01066         /* Arrange to flush cache on pg_operator and pg_cast changes */
01067         CacheRegisterSyscacheCallback(OPERNAMENSP,
01068                                       InvalidateOprCacheCallBack,
01069                                       (Datum) 0);
01070         CacheRegisterSyscacheCallback(CASTSOURCETARGET,
01071                                       InvalidateOprCacheCallBack,
01072                                       (Datum) 0);
01073     }
01074 
01075     /* Look for an existing entry */
01076     oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
01077                                              (void *) key,
01078                                              HASH_FIND, NULL);
01079     if (oprentry == NULL)
01080         return InvalidOid;
01081 
01082     return oprentry->opr_oid;
01083 }
01084 
01085 /*
01086  * make_oper_cache_entry
01087  *
01088  * Insert a cache entry for the given key.
01089  */
01090 static void
01091 make_oper_cache_entry(OprCacheKey *key, Oid opr_oid)
01092 {
01093     OprCacheEntry *oprentry;
01094 
01095     Assert(OprCacheHash != NULL);
01096 
01097     oprentry = (OprCacheEntry *) hash_search(OprCacheHash,
01098                                              (void *) key,
01099                                              HASH_ENTER, NULL);
01100     oprentry->opr_oid = opr_oid;
01101 }
01102 
01103 /*
01104  * Callback for pg_operator and pg_cast inval events
01105  */
01106 static void
01107 InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
01108 {
01109     HASH_SEQ_STATUS status;
01110     OprCacheEntry *hentry;
01111 
01112     Assert(OprCacheHash != NULL);
01113 
01114     /* Currently we just flush all entries; hard to be smarter ... */
01115     hash_seq_init(&status, OprCacheHash);
01116 
01117     while ((hentry = (OprCacheEntry *) hash_seq_search(&status)) != NULL)
01118     {
01119         if (hash_search(OprCacheHash,
01120                         (void *) &hentry->key,
01121                         HASH_REMOVE, NULL) == NULL)
01122             elog(ERROR, "hash table corrupted");
01123     }
01124 }