~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/backend/utils/cache/syscache.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * syscache.c
 
4
 *        System cache management routines
 
5
 *
 
6
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.96 2004-12-31 22:01:25 pgsql Exp $
 
12
 *
 
13
 * NOTES
 
14
 *        These routines allow the parser/planner/executor to perform
 
15
 *        rapid lookups on the contents of the system catalogs.
 
16
 *
 
17
 *        see catalog/syscache.h for a list of the cache id's
 
18
 *
 
19
 *-------------------------------------------------------------------------
 
20
 */
 
21
#include "postgres.h"
 
22
 
 
23
#include "access/heapam.h"
 
24
#include "access/transam.h"
 
25
#include "utils/builtins.h"
 
26
#include "catalog/catname.h"
 
27
#include "catalog/indexing.h"
 
28
#include "catalog/pg_aggregate.h"
 
29
#include "catalog/pg_amop.h"
 
30
#include "catalog/pg_amproc.h"
 
31
#include "catalog/pg_cast.h"
 
32
#include "catalog/pg_conversion.h"
 
33
#include "catalog/pg_group.h"
 
34
#include "catalog/pg_index.h"
 
35
#include "catalog/pg_inherits.h"
 
36
#include "catalog/pg_language.h"
 
37
#include "catalog/pg_namespace.h"
 
38
#include "catalog/pg_opclass.h"
 
39
#include "catalog/pg_operator.h"
 
40
#include "catalog/pg_proc.h"
 
41
#include "catalog/pg_rewrite.h"
 
42
#include "catalog/pg_shadow.h"
 
43
#include "catalog/pg_statistic.h"
 
44
#include "catalog/pg_type.h"
 
45
#include "utils/catcache.h"
 
46
#include "utils/syscache.h"
 
47
#include "miscadmin.h"
 
48
 
 
49
 
 
50
/*---------------------------------------------------------------------------
 
51
 
 
52
        Adding system caches:
 
53
 
 
54
        Add your new cache to the list in include/utils/syscache.h.  Keep
 
55
        the list sorted alphabetically and adjust the cache numbers
 
56
        accordingly.
 
57
 
 
58
        Add your entry to the cacheinfo[] array below.  All cache lists are
 
59
        alphabetical, so add it in the proper place.  Specify the relation
 
60
        name, index name, number of keys, and key attribute numbers.  If the
 
61
        relation contains tuples that are associated with a particular relation
 
62
        (for example, its attributes, rules, triggers, etc) then specify the
 
63
        attribute number that contains the OID of the associated relation.
 
64
        This is used by CatalogCacheFlushRelation() to remove the correct
 
65
        tuples during a table drop or relcache invalidation event.
 
66
 
 
67
        There must be a unique index underlying each syscache (ie, an index
 
68
        whose key is the same as that of the cache).  If there is not one
 
69
        already, add definitions for it to include/catalog/indexing.h: you
 
70
        need a #define for the index name and a DECLARE_UNIQUE_INDEX macro
 
71
        with the actual declaration.  (This will require a catversion.h update,
 
72
        while simply adding/deleting caches only requires a recompile.)
 
73
 
 
74
        Finally, any place your relation gets heap_insert() or
 
75
        heap_update calls, make sure there is a CatalogUpdateIndexes() or
 
76
        similar call.  The heap_* calls do not update indexes.
 
77
 
 
78
        bjm 1999/11/22
 
79
 
 
80
  ---------------------------------------------------------------------------
 
81
*/
 
82
 
 
83
/*
 
84
 *              struct cachedesc: information defining a single syscache
 
85
 */
 
86
struct cachedesc
 
87
{
 
88
        const char *name;                       /* name of the relation being cached */
 
89
        const char *indname;            /* name of index relation for this cache */
 
90
        int                     reloidattr;             /* attr number of rel OID reference, or 0 */
 
91
        int                     nkeys;                  /* # of keys needed for cache lookup */
 
92
        int                     key[4];                 /* attribute numbers of key attrs */
 
93
};
 
94
 
 
95
static const struct cachedesc cacheinfo[] = {
 
96
        {AggregateRelationName,         /* AGGFNOID */
 
97
                AggregateFnoidIndex,
 
98
                0,
 
99
                1,
 
100
                {
 
101
                        Anum_pg_aggregate_aggfnoid,
 
102
                        0,
 
103
                        0,
 
104
                        0
 
105
        }},
 
106
        {AccessMethodRelationName,      /* AMNAME */
 
107
                AmNameIndex,
 
108
                0,
 
109
                1,
 
110
                {
 
111
                        Anum_pg_am_amname,
 
112
                        0,
 
113
                        0,
 
114
                        0
 
115
        }},
 
116
        {AccessMethodRelationName,      /* AMOID */
 
117
                AmOidIndex,
 
118
                0,
 
119
                1,
 
120
                {
 
121
                        ObjectIdAttributeNumber,
 
122
                        0,
 
123
                        0,
 
124
                        0
 
125
        }},
 
126
        {AccessMethodOperatorRelationName,      /* AMOPOPID */
 
127
                AccessMethodOperatorIndex,
 
128
                0,
 
129
                2,
 
130
                {
 
131
                        Anum_pg_amop_amopopr,
 
132
                        Anum_pg_amop_amopclaid,
 
133
                        0,
 
134
                        0
 
135
        }},
 
136
        {AccessMethodOperatorRelationName,      /* AMOPSTRATEGY */
 
137
                AccessMethodStrategyIndex,
 
138
                0,
 
139
                3,
 
140
                {
 
141
                        Anum_pg_amop_amopclaid,
 
142
                        Anum_pg_amop_amopsubtype,
 
143
                        Anum_pg_amop_amopstrategy,
 
144
                        0
 
145
        }},
 
146
        {AccessMethodProcedureRelationName, /* AMPROCNUM */
 
147
                AccessMethodProcedureIndex,
 
148
                0,
 
149
                3,
 
150
                {
 
151
                        Anum_pg_amproc_amopclaid,
 
152
                        Anum_pg_amproc_amprocsubtype,
 
153
                        Anum_pg_amproc_amprocnum,
 
154
                        0
 
155
        }},
 
156
        {AttributeRelationName,         /* ATTNAME */
 
157
                AttributeRelidNameIndex,
 
158
                Anum_pg_attribute_attrelid,
 
159
                2,
 
160
                {
 
161
                        Anum_pg_attribute_attrelid,
 
162
                        Anum_pg_attribute_attname,
 
163
                        0,
 
164
                        0
 
165
        }},
 
166
        {AttributeRelationName,         /* ATTNUM */
 
167
                AttributeRelidNumIndex,
 
168
                Anum_pg_attribute_attrelid,
 
169
                2,
 
170
                {
 
171
                        Anum_pg_attribute_attrelid,
 
172
                        Anum_pg_attribute_attnum,
 
173
                        0,
 
174
                        0
 
175
        }},
 
176
        {
 
177
                CastRelationName,               /* CASTSOURCETARGET */
 
178
                CastSourceTargetIndex,
 
179
                0,
 
180
                2,
 
181
                {
 
182
                        Anum_pg_cast_castsource,
 
183
                        Anum_pg_cast_casttarget,
 
184
                        0,
 
185
                        0
 
186
        }},
 
187
        {OperatorClassRelationName, /* CLAAMNAMENSP */
 
188
                OpclassAmNameNspIndex,
 
189
                0,
 
190
                3,
 
191
                {
 
192
                        Anum_pg_opclass_opcamid,
 
193
                        Anum_pg_opclass_opcname,
 
194
                        Anum_pg_opclass_opcnamespace,
 
195
                        0
 
196
        }},
 
197
        {OperatorClassRelationName, /* CLAOID */
 
198
                OpclassOidIndex,
 
199
                0,
 
200
                1,
 
201
                {
 
202
                        ObjectIdAttributeNumber,
 
203
                        0,
 
204
                        0,
 
205
                        0
 
206
        }},
 
207
        {ConversionRelationName,        /* CONDEFAULT */
 
208
                ConversionDefaultIndex,
 
209
                0,
 
210
                4,
 
211
                {
 
212
                        Anum_pg_conversion_connamespace,
 
213
                        Anum_pg_conversion_conforencoding,
 
214
                        Anum_pg_conversion_contoencoding,
 
215
                        ObjectIdAttributeNumber,
 
216
        }},
 
217
        {ConversionRelationName,        /* CONNAMENSP */
 
218
                ConversionNameNspIndex,
 
219
                0,
 
220
                2,
 
221
                {
 
222
                        Anum_pg_conversion_conname,
 
223
                        Anum_pg_conversion_connamespace,
 
224
                        0,
 
225
                        0
 
226
        }},
 
227
        {ConversionRelationName,        /* CONOID */
 
228
                ConversionOidIndex,
 
229
                0,
 
230
                1,
 
231
                {
 
232
                        ObjectIdAttributeNumber,
 
233
                        0,
 
234
                        0,
 
235
                        0
 
236
        }},
 
237
        {GroupRelationName,                     /* GRONAME */
 
238
                GroupNameIndex,
 
239
                0,
 
240
                1,
 
241
                {
 
242
                        Anum_pg_group_groname,
 
243
                        0,
 
244
                        0,
 
245
                        0
 
246
        }},
 
247
        {GroupRelationName,                     /* GROSYSID */
 
248
                GroupSysidIndex,
 
249
                0,
 
250
                1,
 
251
                {
 
252
                        Anum_pg_group_grosysid,
 
253
                        0,
 
254
                        0,
 
255
                        0
 
256
        }},
 
257
        {IndexRelationName,                     /* INDEXRELID */
 
258
                IndexRelidIndex,
 
259
                Anum_pg_index_indrelid,
 
260
                1,
 
261
                {
 
262
                        Anum_pg_index_indexrelid,
 
263
                        0,
 
264
                        0,
 
265
                        0
 
266
        }},
 
267
        {InheritsRelationName,          /* INHRELID */
 
268
                InheritsRelidSeqnoIndex,
 
269
                Anum_pg_inherits_inhrelid,
 
270
                2,
 
271
                {
 
272
                        Anum_pg_inherits_inhrelid,
 
273
                        Anum_pg_inherits_inhseqno,
 
274
                        0,
 
275
                        0
 
276
        }},
 
277
        {LanguageRelationName,          /* LANGNAME */
 
278
                LanguageNameIndex,
 
279
                0,
 
280
                1,
 
281
                {
 
282
                        Anum_pg_language_lanname,
 
283
                        0,
 
284
                        0,
 
285
                        0
 
286
        }},
 
287
        {LanguageRelationName,          /* LANGOID */
 
288
                LanguageOidIndex,
 
289
                0,
 
290
                1,
 
291
                {
 
292
                        ObjectIdAttributeNumber,
 
293
                        0,
 
294
                        0,
 
295
                        0
 
296
        }},
 
297
        {NamespaceRelationName,         /* NAMESPACENAME */
 
298
                NamespaceNameIndex,
 
299
                0,
 
300
                1,
 
301
                {
 
302
                        Anum_pg_namespace_nspname,
 
303
                        0,
 
304
                        0,
 
305
                        0
 
306
        }},
 
307
        {NamespaceRelationName,         /* NAMESPACEOID */
 
308
                NamespaceOidIndex,
 
309
                0,
 
310
                1,
 
311
                {
 
312
                        ObjectIdAttributeNumber,
 
313
                        0,
 
314
                        0,
 
315
                        0
 
316
        }},
 
317
        {OperatorRelationName,          /* OPERNAMENSP */
 
318
                OperatorNameNspIndex,
 
319
                0,
 
320
                4,
 
321
                {
 
322
                        Anum_pg_operator_oprname,
 
323
                        Anum_pg_operator_oprleft,
 
324
                        Anum_pg_operator_oprright,
 
325
                        Anum_pg_operator_oprnamespace
 
326
        }},
 
327
        {OperatorRelationName,          /* OPEROID */
 
328
                OperatorOidIndex,
 
329
                0,
 
330
                1,
 
331
                {
 
332
                        ObjectIdAttributeNumber,
 
333
                        0,
 
334
                        0,
 
335
                        0
 
336
        }},
 
337
        {ProcedureRelationName,         /* PROCNAMENSP */
 
338
                ProcedureNameNspIndex,
 
339
                0,
 
340
                4,
 
341
                {
 
342
                        Anum_pg_proc_proname,
 
343
                        Anum_pg_proc_pronargs,
 
344
                        Anum_pg_proc_proargtypes,
 
345
                        Anum_pg_proc_pronamespace
 
346
        }},
 
347
        {ProcedureRelationName,         /* PROCOID */
 
348
                ProcedureOidIndex,
 
349
                0,
 
350
                1,
 
351
                {
 
352
                        ObjectIdAttributeNumber,
 
353
                        0,
 
354
                        0,
 
355
                        0
 
356
        }},
 
357
        {RelationRelationName,          /* RELNAMENSP */
 
358
                ClassNameNspIndex,
 
359
                ObjectIdAttributeNumber,
 
360
                2,
 
361
                {
 
362
                        Anum_pg_class_relname,
 
363
                        Anum_pg_class_relnamespace,
 
364
                        0,
 
365
                        0
 
366
        }},
 
367
        {RelationRelationName,          /* RELOID */
 
368
                ClassOidIndex,
 
369
                ObjectIdAttributeNumber,
 
370
                1,
 
371
                {
 
372
                        ObjectIdAttributeNumber,
 
373
                        0,
 
374
                        0,
 
375
                        0
 
376
        }},
 
377
        {RewriteRelationName,           /* RULERELNAME */
 
378
                RewriteRelRulenameIndex,
 
379
                Anum_pg_rewrite_ev_class,
 
380
                2,
 
381
                {
 
382
                        Anum_pg_rewrite_ev_class,
 
383
                        Anum_pg_rewrite_rulename,
 
384
                        0,
 
385
                        0
 
386
        }},
 
387
        {ShadowRelationName,            /* SHADOWNAME */
 
388
                ShadowNameIndex,
 
389
                0,
 
390
                1,
 
391
                {
 
392
                        Anum_pg_shadow_usename,
 
393
                        0,
 
394
                        0,
 
395
                        0
 
396
        }},
 
397
        {ShadowRelationName,            /* SHADOWSYSID */
 
398
                ShadowSysidIndex,
 
399
                0,
 
400
                1,
 
401
                {
 
402
                        Anum_pg_shadow_usesysid,
 
403
                        0,
 
404
                        0,
 
405
                        0
 
406
        }},
 
407
        {StatisticRelationName,         /* STATRELATT */
 
408
                StatisticRelidAttnumIndex,
 
409
                Anum_pg_statistic_starelid,
 
410
                2,
 
411
                {
 
412
                        Anum_pg_statistic_starelid,
 
413
                        Anum_pg_statistic_staattnum,
 
414
                        0,
 
415
                        0
 
416
        }},
 
417
        {TypeRelationName,                      /* TYPENAMENSP */
 
418
                TypeNameNspIndex,
 
419
                Anum_pg_type_typrelid,
 
420
                2,
 
421
                {
 
422
                        Anum_pg_type_typname,
 
423
                        Anum_pg_type_typnamespace,
 
424
                        0,
 
425
                        0
 
426
        }},
 
427
        {TypeRelationName,                      /* TYPEOID */
 
428
                TypeOidIndex,
 
429
                Anum_pg_type_typrelid,
 
430
                1,
 
431
                {
 
432
                        ObjectIdAttributeNumber,
 
433
                        0,
 
434
                        0,
 
435
                        0
 
436
        }}
 
437
};
 
438
 
 
439
static CatCache *SysCache[
 
440
                                                  lengthof(cacheinfo)];
 
441
static int      SysCacheSize = lengthof(cacheinfo);
 
442
static bool CacheInitialized = false;
 
443
 
 
444
 
 
445
/*
 
446
 * InitCatalogCache - initialize the caches
 
447
 *
 
448
 * Note that no database access is done here; we only allocate memory
 
449
 * and initialize the cache structure.  Interrogation of the database
 
450
 * to complete initialization of a cache happens upon first use
 
451
 * of that cache.
 
452
 */
 
453
void
 
454
InitCatalogCache(void)
 
455
{
 
456
        int                     cacheId;
 
457
 
 
458
        Assert(!CacheInitialized);
 
459
 
 
460
        MemSet((char *) SysCache, 0, sizeof(SysCache));
 
461
 
 
462
        for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
 
463
        {
 
464
                SysCache[cacheId] = InitCatCache(cacheId,
 
465
                                                                                 cacheinfo[cacheId].name,
 
466
                                                                                 cacheinfo[cacheId].indname,
 
467
                                                                                 cacheinfo[cacheId].reloidattr,
 
468
                                                                                 cacheinfo[cacheId].nkeys,
 
469
                                                                                 cacheinfo[cacheId].key);
 
470
                if (!PointerIsValid(SysCache[cacheId]))
 
471
                        elog(ERROR, "could not initialize cache %s (%d)",
 
472
                                 cacheinfo[cacheId].name, cacheId);
 
473
        }
 
474
        CacheInitialized = true;
 
475
}
 
476
 
 
477
 
 
478
/*
 
479
 * InitCatalogCachePhase2 - finish initializing the caches
 
480
 *
 
481
 * Finish initializing all the caches, including necessary database
 
482
 * access.
 
483
 *
 
484
 * This is *not* essential; normally we allow syscaches to be initialized
 
485
 * on first use.  However, it is useful as a mechanism to preload the
 
486
 * relcache with entries for the most-commonly-used system catalogs.
 
487
 * Therefore, we invoke this routine when we need to write a new relcache
 
488
 * init file.
 
489
 */
 
490
void
 
491
InitCatalogCachePhase2(void)
 
492
{
 
493
        int                     cacheId;
 
494
 
 
495
        Assert(CacheInitialized);
 
496
 
 
497
        for (cacheId = 0; cacheId < SysCacheSize; cacheId++)
 
498
                InitCatCachePhase2(SysCache[cacheId]);
 
499
}
 
500
 
 
501
 
 
502
/*
 
503
 * SearchSysCache
 
504
 *
 
505
 *      A layer on top of SearchCatCache that does the initialization and
 
506
 *      key-setting for you.
 
507
 *
 
508
 *      Returns the cache copy of the tuple if one is found, NULL if not.
 
509
 *      The tuple is the 'cache' copy and must NOT be modified!
 
510
 *
 
511
 *      When the caller is done using the tuple, call ReleaseSysCache()
 
512
 *      to release the reference count grabbed by SearchSysCache().  If this
 
513
 *      is not done, the tuple will remain locked in cache until end of
 
514
 *      transaction, which is tolerable but not desirable.
 
515
 *
 
516
 *      CAUTION: The tuple that is returned must NOT be freed by the caller!
 
517
 */
 
518
HeapTuple
 
519
SearchSysCache(int cacheId,
 
520
                           Datum key1,
 
521
                           Datum key2,
 
522
                           Datum key3,
 
523
                           Datum key4)
 
524
{
 
525
        if (cacheId < 0 || cacheId >= SysCacheSize ||
 
526
                !PointerIsValid(SysCache[cacheId]))
 
527
                elog(ERROR, "invalid cache id: %d", cacheId);
 
528
 
 
529
        return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);
 
530
}
 
531
 
 
532
/*
 
533
 * ReleaseSysCache
 
534
 *              Release previously grabbed reference count on a tuple
 
535
 */
 
536
void
 
537
ReleaseSysCache(HeapTuple tuple)
 
538
{
 
539
        ReleaseCatCache(tuple);
 
540
}
 
541
 
 
542
/*
 
543
 * SearchSysCacheCopy
 
544
 *
 
545
 * A convenience routine that does SearchSysCache and (if successful)
 
546
 * returns a modifiable copy of the syscache entry.  The original
 
547
 * syscache entry is released before returning.  The caller should
 
548
 * heap_freetuple() the result when done with it.
 
549
 */
 
550
HeapTuple
 
551
SearchSysCacheCopy(int cacheId,
 
552
                                   Datum key1,
 
553
                                   Datum key2,
 
554
                                   Datum key3,
 
555
                                   Datum key4)
 
556
{
 
557
        HeapTuple       tuple,
 
558
                                newtuple;
 
559
 
 
560
        tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
 
561
        if (!HeapTupleIsValid(tuple))
 
562
                return tuple;
 
563
        newtuple = heap_copytuple(tuple);
 
564
        ReleaseSysCache(tuple);
 
565
        return newtuple;
 
566
}
 
567
 
 
568
/*
 
569
 * SearchSysCacheExists
 
570
 *
 
571
 * A convenience routine that just probes to see if a tuple can be found.
 
572
 * No lock is retained on the syscache entry.
 
573
 */
 
574
bool
 
575
SearchSysCacheExists(int cacheId,
 
576
                                         Datum key1,
 
577
                                         Datum key2,
 
578
                                         Datum key3,
 
579
                                         Datum key4)
 
580
{
 
581
        HeapTuple       tuple;
 
582
 
 
583
        tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
 
584
        if (!HeapTupleIsValid(tuple))
 
585
                return false;
 
586
        ReleaseSysCache(tuple);
 
587
        return true;
 
588
}
 
589
 
 
590
/*
 
591
 * GetSysCacheOid
 
592
 *
 
593
 * A convenience routine that does SearchSysCache and returns the OID
 
594
 * of the found tuple, or InvalidOid if no tuple could be found.
 
595
 * No lock is retained on the syscache entry.
 
596
 */
 
597
Oid
 
598
GetSysCacheOid(int cacheId,
 
599
                           Datum key1,
 
600
                           Datum key2,
 
601
                           Datum key3,
 
602
                           Datum key4)
 
603
{
 
604
        HeapTuple       tuple;
 
605
        Oid                     result;
 
606
 
 
607
        tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
 
608
        if (!HeapTupleIsValid(tuple))
 
609
                return InvalidOid;
 
610
        result = HeapTupleGetOid(tuple);
 
611
        ReleaseSysCache(tuple);
 
612
        return result;
 
613
}
 
614
 
 
615
 
 
616
/*
 
617
 * SearchSysCacheAttName
 
618
 *
 
619
 * This routine is equivalent to SearchSysCache on the ATTNAME cache,
 
620
 * except that it will return NULL if the found attribute is marked
 
621
 * attisdropped.  This is convenient for callers that want to act as
 
622
 * though dropped attributes don't exist.
 
623
 */
 
624
HeapTuple
 
625
SearchSysCacheAttName(Oid relid, const char *attname)
 
626
{
 
627
        HeapTuple       tuple;
 
628
 
 
629
        tuple = SearchSysCache(ATTNAME,
 
630
                                                   ObjectIdGetDatum(relid),
 
631
                                                   CStringGetDatum(attname),
 
632
                                                   0, 0);
 
633
        if (!HeapTupleIsValid(tuple))
 
634
                return NULL;
 
635
        if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
 
636
        {
 
637
                ReleaseSysCache(tuple);
 
638
                return NULL;
 
639
        }
 
640
        return tuple;
 
641
}
 
642
 
 
643
/*
 
644
 * SearchSysCacheCopyAttName
 
645
 *
 
646
 * As above, an attisdropped-aware version of SearchSysCacheCopy.
 
647
 */
 
648
HeapTuple
 
649
SearchSysCacheCopyAttName(Oid relid, const char *attname)
 
650
{
 
651
        HeapTuple       tuple,
 
652
                                newtuple;
 
653
 
 
654
        tuple = SearchSysCacheAttName(relid, attname);
 
655
        if (!HeapTupleIsValid(tuple))
 
656
                return tuple;
 
657
        newtuple = heap_copytuple(tuple);
 
658
        ReleaseSysCache(tuple);
 
659
        return newtuple;
 
660
}
 
661
 
 
662
/*
 
663
 * SearchSysCacheExistsAttName
 
664
 *
 
665
 * As above, an attisdropped-aware version of SearchSysCacheExists.
 
666
 */
 
667
bool
 
668
SearchSysCacheExistsAttName(Oid relid, const char *attname)
 
669
{
 
670
        HeapTuple       tuple;
 
671
 
 
672
        tuple = SearchSysCacheAttName(relid, attname);
 
673
        if (!HeapTupleIsValid(tuple))
 
674
                return false;
 
675
        ReleaseSysCache(tuple);
 
676
        return true;
 
677
}
 
678
 
 
679
 
 
680
/*
 
681
 * SysCacheGetAttr
 
682
 *
 
683
 *              Given a tuple previously fetched by SearchSysCache(),
 
684
 *              extract a specific attribute.
 
685
 *
 
686
 * This is equivalent to using heap_getattr() on a tuple fetched
 
687
 * from a non-cached relation.  Usually, this is only used for attributes
 
688
 * that could be NULL or variable length; the fixed-size attributes in
 
689
 * a system table are accessed just by mapping the tuple onto the C struct
 
690
 * declarations from include/catalog/.
 
691
 *
 
692
 * As with heap_getattr(), if the attribute is of a pass-by-reference type
 
693
 * then a pointer into the tuple data area is returned --- the caller must
 
694
 * not modify or pfree the datum!
 
695
 */
 
696
Datum
 
697
SysCacheGetAttr(int cacheId, HeapTuple tup,
 
698
                                AttrNumber attributeNumber,
 
699
                                bool *isNull)
 
700
{
 
701
        /*
 
702
         * We just need to get the TupleDesc out of the cache entry, and then
 
703
         * we can apply heap_getattr().  We expect that the cache control data
 
704
         * is currently valid --- if the caller recently fetched the tuple,
 
705
         * then it should be.
 
706
         */
 
707
        if (cacheId < 0 || cacheId >= SysCacheSize)
 
708
                elog(ERROR, "invalid cache id: %d", cacheId);
 
709
        if (!PointerIsValid(SysCache[cacheId]) ||
 
710
                !PointerIsValid(SysCache[cacheId]->cc_tupdesc))
 
711
                elog(ERROR, "missing cache data for cache id %d", cacheId);
 
712
 
 
713
        return heap_getattr(tup, attributeNumber,
 
714
                                                SysCache[cacheId]->cc_tupdesc,
 
715
                                                isNull);
 
716
}
 
717
 
 
718
/*
 
719
 * List-search interface
 
720
 */
 
721
struct catclist *
 
722
SearchSysCacheList(int cacheId, int nkeys,
 
723
                                   Datum key1, Datum key2, Datum key3, Datum key4)
 
724
{
 
725
        if (cacheId < 0 || cacheId >= SysCacheSize ||
 
726
                !PointerIsValid(SysCache[cacheId]))
 
727
                elog(ERROR, "invalid cache id: %d", cacheId);
 
728
 
 
729
        return SearchCatCacheList(SysCache[cacheId], nkeys,
 
730
                                                          key1, key2, key3, key4);
 
731
}