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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * rewriteSupport.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/rewrite/rewriteSupport.c,v 1.32 1999/02/13 23:17:52 momjian Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "postgres.h"
  15. #include "access/heapam.h"
  16. #include "catalog/catname.h"
  17. #include "catalog/indexing.h"
  18. #include "catalog/pg_class.h"
  19. #include "catalog/pg_rewrite.h"
  20. #include "fmgr.h"
  21. #include "nodes/parsenodes.h"
  22. #include "nodes/pg_list.h"
  23. #include "storage/buf.h" /* for InvalidBuffer */
  24. #include "storage/bufmgr.h"
  25. #include "utils/builtins.h" /* for textout */
  26. #include "utils/catcache.h" /* for CacheContext */
  27. #include "utils/mcxt.h" /* MemoryContext stuff */
  28. #include "utils/rel.h" /* for Relation, RelationData ... */
  29. #include "utils/syscache.h" /* for SearchSysCache */
  30. #include "rewrite/rewriteSupport.h"
  31. /*
  32.  * RuleIdGetActionInfo -
  33.  *    given a rule oid, look it up and return the rule-event-qual and
  34.  *    list of parsetrees for the rule (in parseTrees)
  35.  */
  36. #ifdef NOT_USED
  37. static Node *
  38. RuleIdGetActionInfo(Oid ruleoid, bool *instead_flag, Query **parseTrees)
  39. {
  40. HeapTuple ruletuple;
  41. char    *ruleaction = NULL;
  42. bool action_is_null = false;
  43. bool instead_is_null = false;
  44. Relation ruleRelation = NULL;
  45. TupleDesc ruleTupdesc = NULL;
  46. Query    *ruleparse = NULL;
  47. char    *rule_evqual_string = NULL;
  48. Node    *rule_evqual = NULL;
  49. ruleRelation = heap_openr(RewriteRelationName);
  50. ruleTupdesc = RelationGetDescr(ruleRelation);
  51. ruletuple = SearchSysCacheTuple(RULOID,
  52. ObjectIdGetDatum(ruleoid),
  53. 0, 0, 0);
  54. if (ruletuple == NULL)
  55. elog(ERROR, "rule %u isn't in rewrite system relation", ruleoid);
  56. ruleaction = (char *) heap_getattr(ruletuple,
  57.    Anum_pg_rewrite_ev_action,
  58.    ruleTupdesc,
  59.    &action_is_null);
  60. rule_evqual_string = (char *) heap_getattr(ruletuple,
  61.    Anum_pg_rewrite_ev_qual,
  62.    ruleTupdesc, &action_is_null);
  63. *instead_flag = !!heap_getattr(ruletuple,
  64.    Anum_pg_rewrite_is_instead,
  65.    ruleTupdesc, &instead_is_null);
  66. if (action_is_null || instead_is_null)
  67. elog(ERROR, "internal error: rewrite rule not properly set up");
  68. ruleaction = textout((struct varlena *) ruleaction);
  69. rule_evqual_string = textout((struct varlena *) rule_evqual_string);
  70. ruleparse = (Query *) stringToNode(ruleaction);
  71. rule_evqual = (Node *) stringToNode(rule_evqual_string);
  72. heap_close(ruleRelation);
  73. *parseTrees = ruleparse;
  74. return rule_evqual;
  75. }
  76. #endif
  77. int
  78. IsDefinedRewriteRule(char *ruleName)
  79. {
  80. Relation RewriteRelation = NULL;
  81. HeapTuple tuple;
  82. /*
  83.  * Open the pg_rewrite relation.
  84.  */
  85. RewriteRelation = heap_openr(RewriteRelationName);
  86. tuple = SearchSysCacheTuple(REWRITENAME,
  87. PointerGetDatum(ruleName),
  88. 0, 0, 0);
  89. /*
  90.  * return whether or not the rewrite rule existed
  91.  */
  92. heap_close(RewriteRelation);
  93. return HeapTupleIsValid(tuple);
  94. }
  95. static void
  96. setRelhasrulesInRelation(Oid relationId, bool relhasrules)
  97. {
  98. Relation relationRelation;
  99. HeapTuple tuple;
  100. Relation idescs[Num_pg_class_indices];
  101. /*
  102.  * Lock a relation given its Oid. Go to the RelationRelation (i.e.
  103.  * pg_relation), find the appropriate tuple, and add the specified
  104.  * lock to it.
  105.  */
  106. tuple = SearchSysCacheTupleCopy(RELOID,
  107. ObjectIdGetDatum(relationId),
  108. 0, 0, 0);
  109. Assert(HeapTupleIsValid(tuple));
  110. relationRelation = heap_openr(RelationRelationName);
  111. ((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relhasrules;
  112. heap_replace(relationRelation, &tuple->t_self, tuple, NULL);
  113. /* keep the catalog indices up to date */
  114. CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
  115. CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple);
  116. CatalogCloseIndices(Num_pg_class_indices, idescs);
  117. pfree(tuple);
  118. heap_close(relationRelation);
  119. }
  120. void
  121. prs2_addToRelation(Oid relid,
  122.    Oid ruleId,
  123.    CmdType event_type,
  124.    AttrNumber attno,
  125.    bool isInstead,
  126.    Node *qual,
  127.    List *actions)
  128. {
  129. Relation relation;
  130. RewriteRule *thisRule;
  131. RuleLock   *rulelock;
  132. MemoryContext oldcxt;
  133. /*
  134.  * create an in memory RewriteRule data structure which is cached by
  135.  * every Relation descriptor. (see utils/cache/relcache.c)
  136.  */
  137. oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
  138. thisRule = (RewriteRule *) palloc(sizeof(RewriteRule));
  139. if (qual != NULL)
  140. qual = copyObject(qual);
  141. if (actions != NIL)
  142. actions = copyObject(actions);
  143. MemoryContextSwitchTo(oldcxt);
  144. thisRule->ruleId = ruleId;
  145. thisRule->event = event_type;
  146. thisRule->attrno = attno;
  147. thisRule->qual = qual;
  148. thisRule->actions = actions;
  149. thisRule->isInstead = isInstead;
  150. relation = heap_open(relid);
  151. /*
  152.  * modify or create a RuleLock cached by Relation
  153.  */
  154. if (relation->rd_rules == NULL)
  155. {
  156. oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
  157. rulelock = (RuleLock *) palloc(sizeof(RuleLock));
  158. rulelock->numLocks = 1;
  159. rulelock->rules = (RewriteRule **) palloc(sizeof(RewriteRule *));
  160. rulelock->rules[0] = thisRule;
  161. relation->rd_rules = rulelock;
  162. MemoryContextSwitchTo(oldcxt);
  163. /*
  164.  * the fact that relation->rd_rules is NULL means the relhasrules
  165.  * attribute of the tuple of this relation in pg_class is false.
  166.  * We need to set it to true.
  167.  */
  168. setRelhasrulesInRelation(relid, TRUE);
  169. }
  170. else
  171. {
  172. int numlock;
  173. rulelock = relation->rd_rules;
  174. numlock = rulelock->numLocks;
  175. /* expand, for safety reasons */
  176. oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
  177. rulelock->rules = (RewriteRule **) repalloc(rulelock->rules,
  178.   sizeof(RewriteRule *) * (numlock + 1));
  179. MemoryContextSwitchTo(oldcxt);
  180. rulelock->rules[numlock] = thisRule;
  181. rulelock->numLocks++;
  182. }
  183. heap_close(relation);
  184. return;
  185. }
  186. void
  187. prs2_deleteFromRelation(Oid relid, Oid ruleId)
  188. {
  189. RuleLock   *rulelock;
  190. Relation relation;
  191. int numlock;
  192. int i;
  193. MemoryContext oldcxt;
  194. relation = heap_open(relid);
  195. rulelock = relation->rd_rules;
  196. Assert(rulelock != NULL);
  197. numlock = rulelock->numLocks;
  198. for (i = 0; i < numlock; i++)
  199. {
  200. if (rulelock->rules[i]->ruleId == ruleId)
  201. break;
  202. }
  203. Assert(i < numlock);
  204. oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
  205. pfree(rulelock->rules[i]);
  206. MemoryContextSwitchTo(oldcxt);
  207. if (numlock == 1)
  208. {
  209. relation->rd_rules = NULL;
  210. /*
  211.  * we don't have rules any more, flag the relhasrules attribute of
  212.  * the tuple of this relation in pg_class false.
  213.  */
  214. setRelhasrulesInRelation(relid, FALSE);
  215. }
  216. else
  217. {
  218. rulelock->rules[i] = rulelock->rules[numlock - 1];
  219. rulelock->rules[numlock - 1] = NULL;
  220. rulelock->numLocks--;
  221. }
  222. heap_close(relation);
  223. }