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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * indexing.c
  4.  *   This file contains routines to support indices defined on system
  5.  *   catalogs.
  6.  *
  7.  * Copyright (c) 1994, Regents of the University of California
  8.  *
  9.  *
  10.  * IDENTIFICATION
  11.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.38.2.1 1999/08/02 05:56:54 scrappy Exp $
  12.  *
  13.  *-------------------------------------------------------------------------
  14.  */
  15. #include "postgres.h"
  16. #include "access/genam.h"
  17. #include "access/heapam.h"
  18. #include "catalog/catalog.h"
  19. #include "catalog/catname.h"
  20. #include "catalog/index.h"
  21. #include "catalog/indexing.h"
  22. #include "catalog/pg_index.h"
  23. #include "miscadmin.h"
  24. #include "utils/syscache.h"
  25. #include "utils/temprel.h"
  26. /*
  27.  * Names of indices on the following system catalogs:
  28.  *
  29.  * pg_attribute
  30.  * pg_proc
  31.  * pg_type
  32.  * pg_naming
  33.  * pg_class
  34.  * pg_attrdef
  35.  * pg_relcheck
  36.  * pg_trigger
  37.  */
  38. char    *Name_pg_attr_indices[Num_pg_attr_indices] = {AttributeNameIndex,
  39. AttributeNumIndex,
  40. AttributeRelidIndex};
  41. char    *Name_pg_proc_indices[Num_pg_proc_indices] = {ProcedureNameIndex,
  42. ProcedureOidIndex,
  43. ProcedureSrcIndex};
  44. char    *Name_pg_type_indices[Num_pg_type_indices] = {TypeNameIndex,
  45. TypeOidIndex};
  46. char    *Name_pg_class_indices[Num_pg_class_indices] = {ClassNameIndex,
  47. ClassOidIndex};
  48. char    *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = {AttrDefaultIndex};
  49. char    *Name_pg_relcheck_indices[Num_pg_relcheck_indices] = {RelCheckIndex};
  50. char    *Name_pg_trigger_indices[Num_pg_trigger_indices] = {TriggerRelidIndex};
  51. static HeapTuple CatalogIndexFetchTuple(Relation heapRelation,
  52.    Relation idesc,
  53.    ScanKey skey,
  54.    int16 num_keys);
  55. /*
  56.  * Changes (appends) to catalogs can (and does) happen at various places
  57.  * throughout the code.  We need a generic routine that will open all of
  58.  * the indices defined on a given catalog a return the relation descriptors
  59.  * associated with them.
  60.  */
  61. void
  62. CatalogOpenIndices(int nIndices, char **names, Relation *idescs)
  63. {
  64. int i;
  65. for (i = 0; i < nIndices; i++)
  66. idescs[i] = index_openr(names[i]);
  67. }
  68. /*
  69.  * This is the inverse routine to CatalogOpenIndices()
  70.  */
  71. void
  72. CatalogCloseIndices(int nIndices, Relation *idescs)
  73. {
  74. int i;
  75. for (i = 0; i < nIndices; i++)
  76. index_close(idescs[i]);
  77. }
  78. /*
  79.  * For the same reasons outlined above CatalogOpenIndices() we need a routine
  80.  * that takes a new catalog tuple and inserts an associated index tuple into
  81.  * each catalog index.
  82.  */
  83. void
  84. CatalogIndexInsert(Relation *idescs,
  85.    int nIndices,
  86.    Relation heapRelation,
  87.    HeapTuple heapTuple)
  88. {
  89. HeapTuple index_tup;
  90. TupleDesc heapDescriptor;
  91. Form_pg_index index_form;
  92. Datum datum[INDEX_MAX_KEYS];
  93. char nulls[INDEX_MAX_KEYS];
  94. int natts;
  95. AttrNumber *attnumP;
  96. FuncIndexInfo finfo,
  97.    *finfoP;
  98. int i;
  99. heapDescriptor = RelationGetDescr(heapRelation);
  100. for (i = 0; i < nIndices; i++)
  101. {
  102. InsertIndexResult indexRes;
  103. index_tup = SearchSysCacheTupleCopy(INDEXRELID,
  104.   ObjectIdGetDatum(idescs[i]->rd_id),
  105. 0, 0, 0);
  106. Assert(index_tup);
  107. index_form = (Form_pg_index) GETSTRUCT(index_tup);
  108. if (index_form->indproc != InvalidOid)
  109. {
  110. int fatts;
  111. /*
  112.  * Compute the number of attributes we are indexing upon.
  113.  */
  114. for (attnumP = index_form->indkey, fatts = 0;
  115.  fatts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;
  116.  attnumP++, fatts++)
  117. ;
  118. FIgetnArgs(&finfo) = fatts;
  119. natts = 1;
  120. FIgetProcOid(&finfo) = index_form->indproc;
  121. *(FIgetname(&finfo)) = '';
  122. finfoP = &finfo;
  123. }
  124. else
  125. {
  126. natts = RelationGetDescr(idescs[i])->natts;
  127. finfoP = (FuncIndexInfo *) NULL;
  128. }
  129. FormIndexDatum(natts,
  130.    (AttrNumber *) index_form->indkey,
  131.    heapTuple,
  132.    heapDescriptor,
  133.    datum,
  134.    nulls,
  135.    finfoP);
  136. indexRes = index_insert(idescs[i], datum, nulls,
  137. &heapTuple->t_self, heapRelation);
  138. if (indexRes)
  139. pfree(indexRes);
  140. pfree(index_tup);
  141. }
  142. }
  143. /*
  144.  * This is needed at initialization when reldescs for some of the crucial
  145.  * system catalogs are created and nailed into the cache.
  146.  */
  147. bool
  148. CatalogHasIndex(char *catName, Oid catId)
  149. {
  150. Relation pg_class;
  151. HeapTuple htup;
  152. Form_pg_class pgRelP;
  153. int i;
  154. Assert(IsSystemRelationName(catName));
  155. /*
  156.  * If we're bootstraping we don't have pg_class (or any indices).
  157.  */
  158. if (IsBootstrapProcessingMode())
  159. return false;
  160. if (IsInitProcessingMode())
  161. {
  162. for (i = 0; IndexedCatalogNames[i] != NULL; i++)
  163. {
  164. if (strcmp(IndexedCatalogNames[i], catName) == 0)
  165. return true;
  166. }
  167. return false;
  168. }
  169. pg_class = heap_openr(RelationRelationName);
  170. htup = ClassOidIndexScan(pg_class, catId);
  171. heap_close(pg_class);
  172. if (!HeapTupleIsValid(htup))
  173. {
  174. elog(NOTICE, "CatalogHasIndex: no relation with oid %u", catId);
  175. return false;
  176. }
  177. pgRelP = (Form_pg_class) GETSTRUCT(htup);
  178. return pgRelP->relhasindex;
  179. }
  180. /*
  181.  * CatalogIndexFetchTuple() -- Get a tuple that satisfies a scan key
  182.  * from a catalog relation.
  183.  *
  184.  * Since the index may contain pointers to dead tuples, we need to
  185.  * iterate until we find a tuple that's valid and satisfies the scan
  186.  * key.
  187.  */
  188. static HeapTuple
  189. CatalogIndexFetchTuple(Relation heapRelation,
  190.    Relation idesc,
  191.    ScanKey skey,
  192.    int16 num_keys)
  193. {
  194. IndexScanDesc sd;
  195. RetrieveIndexResult indexRes;
  196. HeapTupleData tuple;
  197. HeapTuple result = NULL;
  198. Buffer buffer;
  199. sd = index_beginscan(idesc, false, num_keys, skey);
  200. tuple.t_data = NULL;
  201. while ((indexRes = index_getnext(sd, ForwardScanDirection)))
  202. {
  203. tuple.t_self = indexRes->heap_iptr;
  204. heap_fetch(heapRelation, SnapshotNow, &tuple, &buffer);
  205. pfree(indexRes);
  206. if (tuple.t_data != NULL)
  207. break;
  208. }
  209. if (tuple.t_data != NULL)
  210. {
  211. result = heap_copytuple(&tuple);
  212. ReleaseBuffer(buffer);
  213. }
  214. index_endscan(sd);
  215. pfree(sd);
  216. return result;
  217. }
  218. /*
  219.  * The remainder of the file is for individual index scan routines.  Each
  220.  * index should be scanned according to how it was defined during bootstrap
  221.  * (that is, functional or normal) and what arguments the cache lookup
  222.  * requires.  Each routine returns the heap tuple that qualifies.
  223.  */
  224. HeapTuple
  225. AttributeNameIndexScan(Relation heapRelation,
  226.    Oid relid,
  227.    char *attname)
  228. {
  229. Relation idesc;
  230. ScanKeyData skey[2];
  231. HeapTuple tuple;
  232. ScanKeyEntryInitialize(&skey[0],
  233.    (bits16) 0x0,
  234.    (AttrNumber) 1,
  235.    (RegProcedure) F_OIDEQ,
  236.    ObjectIdGetDatum(relid));
  237. ScanKeyEntryInitialize(&skey[1],
  238.    (bits16) 0x0,
  239.    (AttrNumber) 2,
  240.    (RegProcedure) F_NAMEEQ,
  241.    NameGetDatum(attname));
  242. idesc = index_openr(AttributeNameIndex);
  243. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
  244. index_close(idesc);
  245. return tuple;
  246. }
  247. HeapTuple
  248. AttributeNumIndexScan(Relation heapRelation,
  249.   Oid relid,
  250.   AttrNumber attnum)
  251. {
  252. Relation idesc;
  253. ScanKeyData skey[2];
  254. HeapTuple tuple;
  255. ScanKeyEntryInitialize(&skey[0],
  256.    (bits16) 0x0,
  257.    (AttrNumber) 1,
  258.    (RegProcedure) F_OIDEQ,
  259.    ObjectIdGetDatum(relid));
  260. ScanKeyEntryInitialize(&skey[1],
  261.    (bits16) 0x0,
  262.    (AttrNumber) 2,
  263.    (RegProcedure) F_INT2EQ,
  264.    Int16GetDatum(attnum));
  265. idesc = index_openr(AttributeNumIndex);
  266. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
  267. index_close(idesc);
  268. return tuple;
  269. }
  270. HeapTuple
  271. ProcedureOidIndexScan(Relation heapRelation, Oid procId)
  272. {
  273. Relation idesc;
  274. ScanKeyData skey[1];
  275. HeapTuple tuple;
  276. ScanKeyEntryInitialize(&skey[0],
  277.    (bits16) 0x0,
  278.    (AttrNumber) 1,
  279.    (RegProcedure) F_OIDEQ,
  280.    ObjectIdGetDatum(procId));
  281. idesc = index_openr(ProcedureOidIndex);
  282. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
  283. index_close(idesc);
  284. return tuple;
  285. }
  286. HeapTuple
  287. ProcedureNameIndexScan(Relation heapRelation,
  288.    char *procName,
  289.    int2 nargs,
  290.    Oid *argTypes)
  291. {
  292. Relation idesc;
  293. ScanKeyData skey[3];
  294. HeapTuple tuple;
  295. ScanKeyEntryInitialize(&skey[0],
  296.    (bits16) 0x0,
  297.    (AttrNumber) 1,
  298.    (RegProcedure) F_NAMEEQ,
  299.    PointerGetDatum(procName));
  300. ScanKeyEntryInitialize(&skey[1],
  301.    (bits16) 0x0,
  302.    (AttrNumber) 2,
  303.    (RegProcedure) F_INT2EQ,
  304.    Int16GetDatum(nargs));
  305. ScanKeyEntryInitialize(&skey[2],
  306.    (bits16) 0x0,
  307.    (AttrNumber) 3,
  308.    (RegProcedure) F_OID8EQ,
  309.    PointerGetDatum(argTypes));
  310. idesc = index_openr(ProcedureNameIndex);
  311. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 3);
  312. index_close(idesc);
  313. return tuple;
  314. }
  315. HeapTuple
  316. ProcedureSrcIndexScan(Relation heapRelation, text *procSrc)
  317. {
  318. Relation idesc;
  319. ScanKeyData skey[1];
  320. HeapTuple tuple;
  321. ScanKeyEntryInitialize(&skey[0],
  322.    (bits16) 0x0,
  323.    (AttrNumber) 1,
  324.    (RegProcedure) F_TEXTEQ,
  325.    PointerGetDatum(procSrc));
  326. idesc = index_openr(ProcedureSrcIndex);
  327. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
  328. index_close(idesc);
  329. return tuple;
  330. }
  331. HeapTuple
  332. TypeOidIndexScan(Relation heapRelation, Oid typeId)
  333. {
  334. Relation idesc;
  335. ScanKeyData skey[1];
  336. HeapTuple tuple;
  337. ScanKeyEntryInitialize(&skey[0],
  338.    (bits16) 0x0,
  339.    (AttrNumber) 1,
  340.    (RegProcedure) F_OIDEQ,
  341.    ObjectIdGetDatum(typeId));
  342. idesc = index_openr(TypeOidIndex);
  343. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
  344. index_close(idesc);
  345. return tuple;
  346. }
  347. HeapTuple
  348. TypeNameIndexScan(Relation heapRelation, char *typeName)
  349. {
  350. Relation idesc;
  351. ScanKeyData skey[1];
  352. HeapTuple tuple;
  353. ScanKeyEntryInitialize(&skey[0],
  354.    (bits16) 0x0,
  355.    (AttrNumber) 1,
  356.    (RegProcedure) F_NAMEEQ,
  357.    PointerGetDatum(typeName));
  358. idesc = index_openr(TypeNameIndex);
  359. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
  360. index_close(idesc);
  361. return tuple;
  362. }
  363. HeapTuple
  364. ClassNameIndexScan(Relation heapRelation, char *relName)
  365. {
  366. Relation idesc;
  367. ScanKeyData skey[1];
  368. HeapTuple tuple;
  369. /*
  370.  * we have to do this before looking in system tables because temp
  371.  * table namespace takes precedence
  372.  */
  373. if ((tuple = get_temp_rel_by_name(relName)) != NULL)
  374. return heap_copytuple(tuple);
  375. ScanKeyEntryInitialize(&skey[0],
  376.    (bits16) 0x0,
  377.    (AttrNumber) 1,
  378.    (RegProcedure) F_NAMEEQ,
  379.    PointerGetDatum(relName));
  380. idesc = index_openr(ClassNameIndex);
  381. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
  382. index_close(idesc);
  383. return tuple;
  384. }
  385. HeapTuple
  386. ClassOidIndexScan(Relation heapRelation, Oid relId)
  387. {
  388. Relation idesc;
  389. ScanKeyData skey[1];
  390. HeapTuple tuple;
  391. ScanKeyEntryInitialize(&skey[0],
  392.    (bits16) 0x0,
  393.    (AttrNumber) 1,
  394.    (RegProcedure) F_OIDEQ,
  395.    ObjectIdGetDatum(relId));
  396. idesc = index_openr(ClassOidIndex);
  397. tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
  398. index_close(idesc);
  399. return tuple;
  400. }