catalog.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * catalog.c
  4.  *
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.21.2.1 1999/08/02 05:56:54 scrappy Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "postgres.h"
  15. #include "access/transam.h"
  16. #include "catalog/catalog.h"
  17. #include "catalog/catname.h"
  18. #include "catalog/pg_type.h"
  19. #include "miscadmin.h"
  20. #include "utils/syscache.h"
  21. /*
  22.  * relpath - path to the relation
  23.  * Perhaps this should be in-line code in relopen().
  24.  */
  25. char *
  26. relpath(char *relname)
  27. {
  28. char    *path;
  29. int bufsize = 0;
  30. if (IsSharedSystemRelationName(relname))
  31. {
  32. bufsize = strlen(DataDir) + sizeof(NameData) + 2;
  33. path = (char *) palloc(bufsize);
  34. snprintf(path, bufsize, "%s/%s", DataDir, relname);
  35. return path;
  36. }
  37. return relname;
  38. }
  39. /*
  40.  * IsSystemRelationName
  41.  * True iff name is the name of a system catalog relation.
  42.  *
  43.  * We now make a new requirement where system catalog relns must begin
  44.  * with pg_ while user relns are forbidden to do so.  Make the test
  45.  * trivial and instantaneous.
  46.  *
  47.  * XXX this is way bogus. -- pma
  48.  */
  49. bool
  50. IsSystemRelationName(char *relname)
  51. {
  52. if (relname[0] && relname[1] && relname[2])
  53. return (relname[0] == 'p' &&
  54. relname[1] == 'g' &&
  55. relname[2] == '_');
  56. else
  57. return FALSE;
  58. }
  59. /*
  60.  * IsSharedSystemRelationName
  61.  * True iff name is the name of a shared system catalog relation.
  62.  */
  63. bool
  64. IsSharedSystemRelationName(char *relname)
  65. {
  66. int i;
  67. /*
  68.  * Quick out: if it's not a system relation, it can't be a shared
  69.  * system relation.
  70.  */
  71. if (!IsSystemRelationName(relname))
  72. return FALSE;
  73. i = 0;
  74. while (SharedSystemRelationNames[i] != NULL)
  75. {
  76. if (strcmp(SharedSystemRelationNames[i], relname) == 0)
  77. return TRUE;
  78. i++;
  79. }
  80. return FALSE;
  81. }
  82. /*
  83.  * newoid - returns a unique identifier across all catalogs.
  84.  *
  85.  * Object Id allocation is now done by GetNewObjectID in
  86.  * access/transam/varsup.c.  oids are now allocated correctly.
  87.  *
  88.  * old comments:
  89.  * This needs to change soon, it fails if there are too many more
  90.  * than one call per second when postgres restarts after it dies.
  91.  *
  92.  * The distribution of OID's should be done by the POSTMASTER.
  93.  * Also there needs to be a facility to preallocate OID's.  Ie.,
  94.  * for a block of OID's to be declared as invalid ones to allow
  95.  * user programs to use them for temporary object identifiers.
  96.  */
  97. Oid
  98. newoid()
  99. {
  100. Oid lastoid;
  101. GetNewObjectId(&lastoid);
  102. if (!OidIsValid(lastoid))
  103. elog(ERROR, "newoid: GetNewObjectId returns invalid oid");
  104. return lastoid;
  105. }
  106. /*
  107.  * fillatt - fills the ATTRIBUTE relation fields from the TYP
  108.  *
  109.  * Expects that the atttypid domain is set for each att[].
  110.  * Returns with the attnum, and attlen domains set.
  111.  * attnum, attproc, atttyparg, ... should be set by the user.
  112.  *
  113.  * In the future, attnum may not be set?!? or may be passed as an arg?!?
  114.  *
  115.  * Current implementation is very inefficient--should cashe the
  116.  * information if this is at all possible.
  117.  *
  118.  * Check to see if this is really needed, and especially in the case
  119.  * of index tuples.
  120.  */
  121. void
  122. fillatt(TupleDesc tupleDesc)
  123. {
  124. Form_pg_attribute *attributeP;
  125. Form_pg_type typp;
  126. HeapTuple tuple;
  127. int i;
  128. int natts = tupleDesc->natts;
  129. Form_pg_attribute *att = tupleDesc->attrs;
  130. if (natts < 0 || natts > MaxHeapAttributeNumber)
  131. elog(ERROR, "fillatt: %d attributes is too large", natts);
  132. if (natts == 0)
  133. {
  134. elog(DEBUG, "fillatt: called with natts == 0");
  135. return;
  136. }
  137. attributeP = &att[0];
  138. for (i = 0; i < natts;)
  139. {
  140. tuple = SearchSysCacheTuple(TYPOID,
  141.    ObjectIdGetDatum((*attributeP)->atttypid),
  142. 0, 0, 0);
  143. if (!HeapTupleIsValid(tuple))
  144. {
  145. elog(ERROR, "fillatt: unknown atttypid %ld",
  146.  (*attributeP)->atttypid);
  147. }
  148. else
  149. {
  150. (*attributeP)->attnum = (int16) ++i;
  151. /*
  152.  * Check if the attr is a set before messing with the length
  153.  * and byval, since those were already set in
  154.  * TupleDescInitEntry. In fact, this seems redundant here,
  155.  * but who knows what I'll break if I take it out...
  156.  */
  157. if (!(*attributeP)->attisset)
  158. {
  159. typp = (Form_pg_type) GETSTRUCT(tuple); /* XXX */
  160. (*attributeP)->attlen = typp->typlen;
  161. (*attributeP)->attbyval = typp->typbyval;
  162. }
  163. }
  164. attributeP += 1;
  165. }
  166. }