~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/backend/parser/parse_oper.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

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