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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * sets.c
  4.  *   Functions for sets, which are defined by queries.
  5.  *   Example:  a set is defined as being the result of the query
  6.  * retrieve (X.all)
  7.  *
  8.  * Copyright (c) 1994, Regents of the University of California
  9.  *
  10.  *
  11.  * IDENTIFICATION
  12.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/sets.c,v 1.21.2.1 1999/08/02 05:24:57 scrappy Exp $
  13.  *
  14.  *-------------------------------------------------------------------------
  15.  */
  16. #include "postgres.h"
  17. #include "access/heapam.h"
  18. #include "catalog/catname.h"
  19. #include "catalog/indexing.h"
  20. #include "catalog/pg_proc.h"
  21. #include "utils/sets.h"
  22. #include "utils/syscache.h"
  23. extern CommandDest whereToSendOutput; /* defined in tcop/postgres.c */
  24. /*
  25.  *   SetDefine    - converts query string defining set to an oid
  26.  *
  27.  *   The query string is used to store the set as a function in
  28.  *   pg_proc. The name of the function is then changed to use the
  29.  *   OID of its tuple in pg_proc.
  30.  */
  31. Oid
  32. SetDefine(char *querystr, char *typename)
  33. {
  34. Oid setoid;
  35. char    *procname = GENERICSETNAME;
  36. char    *fileName = "-";
  37. char realprocname[NAMEDATALEN];
  38. HeapTuple tup,
  39. newtup = NULL;
  40. Form_pg_proc proc;
  41. Relation procrel;
  42. int i;
  43. Datum replValue[Natts_pg_proc];
  44. char replNull[Natts_pg_proc];
  45. char repl[Natts_pg_proc];
  46. setoid = ProcedureCreate(procname, /* changed below, after oid known */
  47.  true, /* returnsSet */
  48.  typename, /* returnTypeName */
  49.  "sql", /* languageName */
  50.  querystr, /* sourceCode */
  51.  fileName, /* fileName */
  52.  false, /* canCache */
  53.  true, /* trusted */
  54.  100, /* byte_pct */
  55.  0, /* perbyte_cpu */
  56.  0, /* percall_cpu */
  57.  100, /* outin_ratio */
  58.  NIL, /* argList */
  59.  whereToSendOutput);
  60. /*
  61.  * Since we're still inside this command of the transaction, we can't
  62.  * see the results of the procedure definition unless we pretend we've
  63.  * started the next command.  (Postgres's solution to the Halloween
  64.  * problem is to not allow you to see the results of your command
  65.  * until you start the next command.)
  66.  */
  67. CommandCounterIncrement();
  68. tup = SearchSysCacheTuple(PROOID,
  69.   ObjectIdGetDatum(setoid),
  70.   0, 0, 0);
  71. if (!HeapTupleIsValid(tup))
  72. elog(ERROR, "setin: unable to define set %s", querystr);
  73. /*
  74.  * We can tell whether the set was already defined by checking the
  75.  * name.   If it's GENERICSETNAME, the set is new.  If it's "set<some
  76.  * oid>" it's already defined.
  77.  */
  78. proc = (Form_pg_proc) GETSTRUCT(tup);
  79. if (!strcmp((char *) procname, (char *) &(proc->proname)))
  80. {
  81. /* make the real proc name */
  82. sprintf(realprocname, "set%u", setoid);
  83. /* set up the attributes to be modified or kept the same */
  84. repl[0] = 'r';
  85. for (i = 1; i < Natts_pg_proc; i++)
  86. repl[i] = ' ';
  87. replValue[0] = (Datum) realprocname;
  88. for (i = 1; i < Natts_pg_proc; i++)
  89. replValue[i] = (Datum) 0;
  90. for (i = 0; i < Natts_pg_proc; i++)
  91. replNull[i] = ' ';
  92. /* change the pg_proc tuple */
  93. procrel = heap_openr(ProcedureRelationName);
  94. LockRelation(procrel, AccessExclusiveLock);
  95. tup = SearchSysCacheTuple(PROOID,
  96.   ObjectIdGetDatum(setoid),
  97.   0, 0, 0);
  98. if (HeapTupleIsValid(tup))
  99. {
  100. newtup = heap_modifytuple(tup,
  101.   procrel,
  102.   replValue,
  103.   replNull,
  104.   repl);
  105. setheapoverride(true);
  106. heap_replace(procrel, &tup->t_self, newtup, NULL);
  107. setheapoverride(false);
  108. setoid = newtup->t_data->t_oid;
  109. }
  110. else
  111. elog(ERROR, "setin: could not find new set oid tuple");
  112. if (RelationGetForm(procrel)->relhasindex)
  113. {
  114. Relation idescs[Num_pg_proc_indices];
  115. CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices, idescs);
  116. CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
  117. CatalogCloseIndices(Num_pg_proc_indices, idescs);
  118. }
  119. UnlockRelation(procrel, AccessExclusiveLock);
  120. heap_close(procrel);
  121. }
  122. return setoid;
  123. }
  124. /* This function is a placeholder. The parser uses the OID of this
  125.  * function to fill in the :funcid field  of a set.  This routine is
  126.  * never executed. At runtime, the OID of the actual set is substituted
  127.  * into the :funcid.
  128.  */
  129. int
  130. seteval(Oid funcoid)
  131. {
  132. return 17;
  133. }