lsyscache.c 9.68 KB
Newer Older
1 2 3
/*-------------------------------------------------------------------------
 *
 * lsyscache.c--
4
 *	  Routines to access information within system caches
5 6 7 8 9
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
Bruce Momjian's avatar
Bruce Momjian committed
10
 *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.17 1998/08/11 14:32:01 momjian Exp $
11 12
 *
 * NOTES
13 14 15 16 17
 *	  Eventually, the index information should go through here, too.
 *
 *	  Most of these routines call SearchSysCacheStruct() and thus simply
 *	  (1) allocate some space for the return struct and (2) call it.
 *
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *-------------------------------------------------------------------------
 */
#include <string.h>
#include "postgres.h"

#include "nodes/pg_list.h"
#include "utils/syscache.h"
#include "utils/lsyscache.h"
#include "access/tupmacs.h"
#include "utils/rel.h"
#include "utils/palloc.h"
#include "utils/elog.h"
#include "access/attnum.h"
#include "access/heapam.h"

#include "catalog/pg_amop.h"
Bruce Momjian's avatar
Bruce Momjian committed
34
#include "catalog/pg_operator.h"
35 36
#include "catalog/pg_type.h"

37
/*				---------- AMOP CACHES ----------						 */
38

39
/*
40
 * op_class -
41 42 43
 *
 *		Return t iff operator 'opno' is in operator class 'opclass'.
 *
44 45
 */
bool
Bruce Momjian's avatar
Bruce Momjian committed
46
op_class(Oid oprno, int32 opclass, Oid amopid)
47
{
48 49 50 51 52 53 54 55
	FormData_pg_amop amoptup;

	if (SearchSysCacheStruct(AMOPOPID,
							 (char *) &amoptup,
							 ObjectIdGetDatum(opclass),
							 ObjectIdGetDatum(opno),
							 ObjectIdGetDatum(amopid),
							 0))
Bruce Momjian's avatar
Bruce Momjian committed
56
		return true;
57
	else
Bruce Momjian's avatar
Bruce Momjian committed
58
		return false;
59 60
}

61
/*				---------- ATTRIBUTE CACHES ----------					 */
62

63
/*
64
 * get_attname -
65 66 67 68
 *
 *		Given the relation id and the attribute number,
 *		return the "attname" field from the attribute relation.
 *
69
 */
70
char *
71 72
get_attname(Oid relid, AttrNumber attnum)
{
73 74 75 76 77 78 79
	FormData_pg_attribute att_tup;

	if (SearchSysCacheStruct(ATTNUM,
							 (char *) &att_tup,
							 ObjectIdGetDatum(relid),
							 UInt16GetDatum(attnum),
							 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
80
		return pstrdup(att_tup.attname.data);
81
	else
Bruce Momjian's avatar
Bruce Momjian committed
82
		return NULL;
83 84
}

85
/*
86
 * get_attnum -
87 88 89 90
 *
 *		Given the relation id and the attribute name,
 *		return the "attnum" field from the attribute relation.
 *
91 92 93 94
 */
AttrNumber
get_attnum(Oid relid, char *attname)
{
95 96 97 98 99 100
	FormData_pg_attribute att_tup;

	if (SearchSysCacheStruct(ATTNAME, (char *) &att_tup,
							 ObjectIdGetDatum(relid),
							 PointerGetDatum(attname),
							 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
101
		return att_tup.attnum;
102
	else
Bruce Momjian's avatar
Bruce Momjian committed
103
		return InvalidAttrNumber;
104 105
}

106
/*
107
 * get_atttype -
108 109 110 111
 *
 *		Given the relation OID and the attribute number with the relation,
 *		return the attribute type OID.
 *
112 113 114 115
 */
Oid
get_atttype(Oid relid, AttrNumber attnum)
{
116 117 118 119 120 121 122
	AttributeTupleForm att_tup = (AttributeTupleForm) palloc(sizeof(*att_tup));

	if (SearchSysCacheStruct(ATTNUM,
							 (char *) att_tup,
							 ObjectIdGetDatum(relid),
							 UInt16GetDatum(attnum),
							 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
123
		return att_tup->atttypid;
124
	else
Bruce Momjian's avatar
Bruce Momjian committed
125
		return (Oid) NULL;
126 127 128 129 130 131 132 133 134
}

/* This routine uses the attname instead of the attnum because it
 * replaces the routine find_atttype, which is called sometimes when
 * only the attname, not the attno, is available.
 */
bool
get_attisset(Oid relid, char *attname)
{
135 136
	HeapTuple	htup;
	AttrNumber	attno;
137 138 139 140 141 142 143 144 145
	AttributeTupleForm att_tup;

	attno = get_attnum(relid, attname);

	htup = SearchSysCacheTuple(ATTNAME,
							   ObjectIdGetDatum(relid),
							   PointerGetDatum(attname),
							   0, 0);
	if (!HeapTupleIsValid(htup))
146
		elog(ERROR, "get_attisset: no attribute %s in relation %d",
147 148
			 attname, relid);
	if (heap_attisnull(htup, attno))
Bruce Momjian's avatar
Bruce Momjian committed
149
		return false;
150 151 152
	else
	{
		att_tup = (AttributeTupleForm) GETSTRUCT(htup);
Bruce Momjian's avatar
Bruce Momjian committed
153
		return att_tup->attisset;
154
	}
155 156
}

Bruce Momjian's avatar
Bruce Momjian committed
157 158 159 160 161 162 163
/*
 * get_atttypmod -
 *
 *		Given the relation id and the attribute number,
 *		return the "atttypmod" field from the attribute relation.
 *
 */
164
int32
Bruce Momjian's avatar
Bruce Momjian committed
165 166 167 168 169 170 171
get_atttypmod(Oid relid, AttrNumber attnum)
{
	FormData_pg_attribute att_tup;

	if (SearchSysCacheStruct(ATTNUM,
							 (char *) &att_tup,
							 ObjectIdGetDatum(relid),
172
							 Int32GetDatum(attnum),
Bruce Momjian's avatar
Bruce Momjian committed
173 174 175
							 0, 0))
		return att_tup.atttypmod;
	else
176
		return -1;
Bruce Momjian's avatar
Bruce Momjian committed
177 178
}

179
/*				---------- INDEX CACHE ----------						 */
180

181
/*		watch this space...
182 183
 */

184
/*				---------- OPERATOR CACHE ----------					 */
185

186
/*
187
 * get_opcode -
188 189 190 191
 *
 *		Returns the regproc id of the routine used to implement an
 *		operator given the operator uid.
 *
192 193 194 195
 */
RegProcedure
get_opcode(Oid opno)
{
196 197 198 199 200
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
201
		return optup.oprcode;
202
	else
Bruce Momjian's avatar
Bruce Momjian committed
203
		return (RegProcedure) NULL;
204 205 206 207
}

/*
 * get_opname -
208
 *	  returns the name of the operator with the given opno
209 210 211
 *
 * Note: return the struct so that it gets copied.
 */
212
char *
213 214
get_opname(Oid opno)
{
215 216 217 218 219
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
220
		return pstrdup(optup.oprname.data);
221 222
	else
	{
223
		elog(ERROR, "can't look up operator %d\n", opno);
224 225
		return NULL;
	}
226 227
}

228
/*
229
 * op_mergejoinable -
230 231
 *
 *		Returns the left and right sort operators and types corresponding to a
232
 *		mergejoinable operator, or nil if the operator is not mergejoinable.
233
 *
234 235
 */
bool
236
op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
237
{
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0) &&
		optup.oprlsortop &&
		optup.oprrsortop &&
		optup.oprleft == ltype &&
		optup.oprright == rtype)
	{

		*leftOp = ObjectIdGetDatum(optup.oprlsortop);
		*rightOp = ObjectIdGetDatum(optup.oprrsortop);
		return TRUE;
	}
	else
		return FALSE;
255 256
}

257
/*
258
 * op_hashjoinable--
259 260
 *
 * Returns the hash operator corresponding to a hashjoinable operator,
261
 * or nil if the operator is not hashjoinable.
262
 *
263 264 265 266
 */
Oid
op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
{
267 268 269 270 271 272 273 274
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0) &&
		optup.oprcanhash &&
		optup.oprleft == ltype &&
		optup.oprright == rtype)
Bruce Momjian's avatar
Bruce Momjian committed
275
		return opno;
276
	else
Bruce Momjian's avatar
Bruce Momjian committed
277
		return InvalidOid;
278 279
}

280
/*
281
 * get_commutator -
282 283 284
 *
 *		Returns the corresponding commutator of an operator.
 *
285 286 287 288
 */
Oid
get_commutator(Oid opno)
{
289 290 291 292 293
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
294
		return optup.oprcom;
295
	else
Bruce Momjian's avatar
Bruce Momjian committed
296
		return (Oid) NULL;
297 298 299 300 301
}

HeapTuple
get_operator_tuple(Oid opno)
{
302
	HeapTuple	optup;
303 304 305 306

	if ((optup = SearchSysCacheTuple(OPROID,
									 ObjectIdGetDatum(opno),
									 0, 0, 0)))
Bruce Momjian's avatar
Bruce Momjian committed
307
		return optup;
308
	else
Bruce Momjian's avatar
Bruce Momjian committed
309
		return (HeapTuple) NULL;
310 311
}

312
/*
313
 * get_negator -
314 315 316
 *
 *		Returns the corresponding negator of an operator.
 *
317 318 319 320
 */
Oid
get_negator(Oid opno)
{
321 322 323 324 325
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
326
		return optup.oprnegate;
327
	else
Bruce Momjian's avatar
Bruce Momjian committed
328
		return (Oid) NULL;
329 330
}

331
/*
332
 * get_oprrest -
333 334 335
 *
 *		Returns procedure id for computing selectivity of an operator.
 *
336 337 338 339
 */
RegProcedure
get_oprrest(Oid opno)
{
340 341 342 343 344
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
345
		return optup.oprrest;
346
	else
Bruce Momjian's avatar
Bruce Momjian committed
347
		return (RegProcedure) NULL;
348 349
}

350
/*
351
 * get_oprjoin -
352 353 354
 *
 *		Returns procedure id for computing selectivity of a join.
 *
355 356 357 358
 */
RegProcedure
get_oprjoin(Oid opno)
{
359 360 361 362 363
	FormData_pg_operator optup;

	if (SearchSysCacheStruct(OPROID, (char *) &optup,
							 ObjectIdGetDatum(opno),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
364
		return optup.oprjoin;
365
	else
Bruce Momjian's avatar
Bruce Momjian committed
366
		return (RegProcedure) NULL;
367 368
}

369
/*				---------- RELATION CACHE ----------					 */
370

371
/*
372
 * get_relnatts -
373 374 375
 *
 *		Returns the number of attributes for a given relation.
 *
376 377 378 379
 */
int
get_relnatts(Oid relid)
{
380 381 382 383 384
	FormData_pg_class reltup;

	if (SearchSysCacheStruct(RELOID, (char *) &reltup,
							 ObjectIdGetDatum(relid),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
385
		return reltup.relnatts;
386
	else
Bruce Momjian's avatar
Bruce Momjian committed
387
		return InvalidAttrNumber;
388 389
}

390
/*
391
 * get_rel_name -
392 393 394
 *
 *		Returns the name of a given relation.
 *
395
 */
396
char *
397 398
get_rel_name(Oid relid)
{
399 400 401 402 403 404
	FormData_pg_class reltup;

	if ((SearchSysCacheStruct(RELOID,
							  (char *) &reltup,
							  ObjectIdGetDatum(relid),
							  0, 0, 0)))
Bruce Momjian's avatar
Bruce Momjian committed
405
		return pstrdup(reltup.relname.data);
406
	else
Bruce Momjian's avatar
Bruce Momjian committed
407
		return NULL;
408 409
}

410
/*				---------- TYPE CACHE ----------						 */
411

412
/*
413
 * get_typlen -
414 415 416
 *
 *		Given the type OID, return the length of the type.
 *
417 418 419 420
 */
int16
get_typlen(Oid typid)
{
421 422 423 424 425
	TypeTupleFormData typtup;

	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
							 ObjectIdGetDatum(typid),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
426
		return typtup.typlen;
427
	else
Bruce Momjian's avatar
Bruce Momjian committed
428
		return (int16) NULL;
429 430
}

431
/*
432
 * get_typbyval -
433 434 435 436
 *
 *		Given the type OID, determine whether the type is returned by value or
 *		not.  Returns 1 if by value, 0 if by reference.
 *
437 438 439 440
 */
bool
get_typbyval(Oid typid)
{
441 442 443 444 445
	TypeTupleFormData typtup;

	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
							 ObjectIdGetDatum(typid),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
446
		return (bool) typtup.typbyval;
447
	else
Bruce Momjian's avatar
Bruce Momjian committed
448
		return false;
449 450
}

451
/*
452
 * get_typbyval -
453 454 455 456
 *
 *		Given the type OID, determine whether the type is returned by value or
 *		not.  Returns 1 if by value, 0 if by reference.
 *
457
 */
458
#ifdef NOT_USED
459 460 461
char
get_typalign(Oid typid)
{
462 463 464 465 466
	TypeTupleFormData typtup;

	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
							 ObjectIdGetDatum(typid),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
467
		return typtup.typalign;
468
	else
Bruce Momjian's avatar
Bruce Momjian committed
469
		return 'i';
470
}
471

472
#endif
473

474 475 476 477 478
/*
 * get_typdefault -
 *
 *		Given the type OID, return the default value of the ADT.
 *
479 480 481 482
 */
struct varlena *
get_typdefault(Oid typid)
{
483 484 485
	struct varlena *typdefault =
	(struct varlena *) TypeDefaultRetrieve(typid);

Bruce Momjian's avatar
Bruce Momjian committed
486
	return typdefault;
487 488
}

489
/*
490
 * get_typtype -
491 492 493 494 495
 *
 *		Given the type OID, find if it is a basic type, a named relation
 *		or the generic type 'relation'.
 *		It returns the null char if the cache lookup fails...
 *
496
 */
497
#ifdef NOT_USED
498 499 500
char
get_typtype(Oid typid)
{
501 502 503 504 505
	TypeTupleFormData typtup;

	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
							 ObjectIdGetDatum(typid),
							 0, 0, 0))
Bruce Momjian's avatar
Bruce Momjian committed
506
		return typtup.typtype;
507
	else
Bruce Momjian's avatar
Bruce Momjian committed
508
		return '\0';
509
}
510

511
#endif