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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * version.c
  4.  *   This file contains all the rules that govern all version semantics.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  * The version stuff has not been tested under postgres95 and probably
  9.  * doesn't work! - jolly 8/19/95
  10.  *
  11.  *
  12.  * $Id: version.c,v 1.19.2.1 1999/08/02 05:57:02 scrappy Exp $
  13.  *
  14.  * NOTES
  15.  * At the point the version is defined, 2 physical relations are created
  16.  * <vname>_added and <vname>_deleted.
  17.  *
  18.  * In addition, 4 rules are defined which govern the semantics of
  19.  * versions w.r.t retrieves, appends, replaces and deletes.
  20.  *
  21.  *-------------------------------------------------------------------------
  22.  */
  23. #include "postgres.h"
  24. #define MAX_QUERY_LEN 1024
  25. char rule_buf[MAX_QUERY_LEN];
  26. /*
  27.  * problem: the version system assumes that the rules it declares will
  28.  * be fired in the order of declaration, it also assumes
  29.  * goh's silly instead semantics.  Unfortunately, it is a pain
  30.  * to make the version system work with the new semantics.
  31.  * However the whole problem can be solved, and some nice
  32.  * functionality can be achieved if we get multiple action rules
  33.  * to work.  So thats what I did -- glass
  34.  *
  35.  * Well, at least they've been working for about 20 minutes.
  36.  *
  37.  * So any comments in this code about 1 rule per transction are false...:)
  38.  *
  39.  */
  40. /*
  41.  * This is needed because the rule system only allows
  42.  * *1* rule to be defined per transaction.
  43.  *
  44.  * NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  45.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  46.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  47.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  48.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  49.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  50.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  51.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  52.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  53.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  54.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  55.  * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  56.  * OOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  57.  *
  58.  * DONT DO THAT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  59.  *
  60.  * If you commit the current Xact all the palloced memory GOES AWAY
  61.  * and could be re-palloced in the new Xact and the whole hell breaks
  62.  * loose and poor people like me spend 2 hours of their live chassing
  63.  * a strange memory bug instead of watching the "Get Smart" marathon
  64.  * in NICK !
  65.  * DO NOT COMMIT THE XACT, just increase the Cid counter!
  66.  * _sp.
  67.  */
  68. #ifdef NOT_USED
  69. static void
  70. eval_as_new_xact(char *query)
  71. {
  72. /*
  73.  * WARNING! do not uncomment the following lines WARNING!
  74.  * CommitTransactionCommand(); StartTransactionCommand();
  75.  */
  76. CommandCounterIncrement();
  77. pg_exec_query(query);
  78. }
  79. #endif
  80. /*
  81.  * Define a version.
  82.  */
  83. #ifdef NOT_USED
  84. void
  85. DefineVersion(char *name, char *fromRelname, char *date)
  86. {
  87. char    *bname;
  88. static char saved_basename[512];
  89. static char saved_snapshot[512];
  90. if (date == NULL)
  91. {
  92. /* no time ranges */
  93. bname = fromRelname;
  94. strcpy(saved_basename, (char *) bname);
  95. *saved_snapshot = (char) NULL;
  96. }
  97. else
  98. {
  99. /* version is a snapshot */
  100. bname = fromRelname;
  101. strcpy(saved_basename, (char *) bname);
  102. sprintf(saved_snapshot, "['%s']", date);
  103. }
  104. /*
  105.  * Calls the routine ``GetAttrList'' get the list of attributes from
  106.  * the base relation. Code is put here so that we only need to look up
  107.  * the attribute once for both appends and replaces.
  108.  */
  109. setAttrList(bname);
  110. VersionCreate(name, saved_basename);
  111. VersionAppend(name, saved_basename);
  112. VersionDelete(name, saved_basename, saved_snapshot);
  113. VersionReplace(name, saved_basename, saved_snapshot);
  114. VersionRetrieve(name, saved_basename, saved_snapshot);
  115. }
  116. #endif
  117. /*
  118.  * Creates the deltas.
  119.  */
  120. #ifdef NOT_USED
  121. void
  122. VersionCreate(char *vname, char *bname)
  123. {
  124. static char query_buf[MAX_QUERY_LEN];
  125. /*
  126.  * Creating the dummy version relation for triggering rules.
  127.  */
  128. sprintf(query_buf, "SELECT * INTO TABLE %s from %s where 1 =2",
  129. vname, bname);
  130. pg_exec_query(query_buf);
  131. /*
  132.  * Creating the ``v_added'' relation
  133.  */
  134. sprintf(query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
  135. vname, bname);
  136. eval_as_new_xact(query_buf);
  137. /*
  138.  * Creating the ``v_deleted'' relation.
  139.  */
  140. sprintf(query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
  141. eval_as_new_xact(query_buf);
  142. }
  143. #endif
  144. /*
  145.  * Given the relation name, does a catalog lookup for that relation and
  146.  * sets the global variable 'attr_list' with the list of attributes (names)
  147.  * for that relation.
  148.  */
  149. #ifdef NOT_USED
  150. static void
  151. setAttrList(char *bname)
  152. {
  153. Relation rel;
  154. int i = 0;
  155. int maxattrs = 0;
  156. char    *attrname;
  157. char temp_buf[512];
  158. int notfirst = 0;
  159. rel = heap_openr(bname);
  160. if (rel == NULL)
  161. {
  162. elog(ERROR, "Unable to expand all -- amopenr failed ");
  163. return;
  164. }
  165. maxattrs = RelationGetNumberOfAttributes(rel);
  166. attr_list[0] = '';
  167. for (i = maxattrs - 1; i > -1; --i)
  168. {
  169. attrname = (rel->rd_att->attrs[i]->attname).data;
  170. if (notfirst == 1)
  171. sprintf(temp_buf, ", %s = new.%s", attrname, attrname);
  172. else
  173. {
  174. sprintf(temp_buf, "%s = new.%s", attrname, attrname);
  175. notfirst = 1;
  176. }
  177. strcat(attr_list, temp_buf);
  178. }
  179. heap_close(rel);
  180. return;
  181. }
  182. #endif
  183. /*
  184.  * This routine defines the rule governing the append semantics of
  185.  * versions.  All tuples appended to a version gets appended to the
  186.  * <vname>_added relation.
  187.  */
  188. #ifdef NOT_USED
  189. static void
  190. VersionAppend(char *vname, char *bname)
  191. {
  192. sprintf(rule_buf,
  193. "define rewrite rule %s_append is on INSERT to %s do instead append %s_added(%s)",
  194. vname, vname, vname, attr_list);
  195. eval_as_new_xact(rule_buf);
  196. }
  197. #endif
  198. /*
  199.  * This routine defines the rule governing the retrieval semantics of
  200.  * versions.  To retrieve tuples from a version , we need to:
  201.  *
  202.  * 1. Retrieve all tuples in the <vname>_added relation.
  203.  * 2. Retrieve all tuples in the base relation which are not in
  204.  *    the <vname>_del relation.
  205.  */
  206. #ifdef NOT_USED
  207. void
  208. VersionRetrieve(char *vname, char *bname, char *snapshot)
  209. {
  210. sprintf(rule_buf,
  211. "define rewrite rule %s_retrieve is on SELECT to %s do insteadn
  212. SELECT %s_1.oid, %s_1.* from _%s in %s%s, %s_1 in (%s_added | _%s) 
  213. where _%s.oid !!= '%s_del.DOID'",
  214. vname, vname, vname, vname, bname,
  215. bname, snapshot,
  216. vname, vname, bname, bname, vname);
  217. eval_as_new_xact(rule_buf);
  218. /* printf("%sn",rule_buf); */
  219. }
  220. #endif
  221. /*
  222.  * This routine defines the rules that govern the delete semantics of
  223.  * versions. Two things happens when we delete a tuple from a version:
  224.  *
  225.  *    1. If the tuple to be deleted was added to the version *after*
  226.  *   the version was created, then we simply delete the tuple
  227.  *   from the <vname>_added relation.
  228.  *    2. If the tuple to be deleted is actually in the base relation,
  229.  *   then we have to mark that tuple as being deleted by adding
  230.  *   it to the <vname>_del relation.
  231.  */
  232. #ifdef NOT_USED
  233. void
  234. VersionDelete(char *vname, char *bname, char *snapshot)
  235. {
  236. sprintf(rule_buf,
  237. "define rewrite rule %s_delete1 is on delete to %s do insteadn 
  238. [delete %s_added where current.oid = %s_added.oidn 
  239.  append %s_del(DOID = current.oid) from _%s in %s%s 
  240.  where current.oid = _%s.oid] n",
  241. vname, vname, vname, vname, vname,
  242. bname, bname, snapshot, bname);
  243. eval_as_new_xact(rule_buf);
  244. #ifdef OLD_REWRITE
  245. sprintf(rule_buf,
  246. "define rewrite rule %s_delete2 is on delete to %s do instead n 
  247.     append %s_del(DOID = current.oid) from _%s in %s%s 
  248.     where current.oid = _%s.oid n",
  249. vname, vname, vname, bname, bname, snapshot, bname);
  250. eval_as_new_xact(rule_buf);
  251. #endif  /* OLD_REWRITE */
  252. }
  253. #endif
  254. /*
  255.  * This routine defines the rules that govern the update semantics
  256.  * of versions. To update a tuple in a version:
  257.  *
  258.  * 1. If the tuple is in <vname>_added, we simply ``replace''
  259.  *    the tuple (as per postgres style).
  260.  * 2. if the tuple is in the base relation, then two things have to
  261.  *    happen:
  262.  *    2.1 The tuple is marked ``deleted'' from the base relation by
  263.  * adding the tuple to the <vname>_del relation.
  264.  *    2.2 A copy of the tuple is appended to the <vname>_added relation
  265.  */
  266. #ifdef NOT_USED
  267. void
  268. VersionReplace(char *vname, char *bname, char *snapshot)
  269. {
  270. sprintf(rule_buf,
  271. "define rewrite rule %s_replace1 is on replace to %s do instead n
  272. [replace %s_added(%s) where current.oid = %s_added.oid n
  273.  append %s_del(DOID = current.oid) from _%s in %s%s 
  274.  where current.oid = _%s.oidn
  275.  append %s_added(%s) from _%s in %s%s 
  276.  where current.oid !!= '%s_added.oid' and current.oid = _%s.oid]n",
  277. vname, vname, vname, attr_list, vname,
  278. vname, bname, bname, snapshot, bname,
  279. vname, attr_list, bname, bname, snapshot, vname, bname);
  280. eval_as_new_xact(rule_buf);
  281. /* printf("%sn",rule_buf); */
  282. #ifdef OLD_REWRITE
  283. sprintf(rule_buf,
  284. "define rewrite rule %s_replace2 is on replace to %s do n
  285.     append %s_del(DOID = current.oid) from _%s in %s%s 
  286.     where current.oid = _%s.oidn",
  287. vname, vname, vname, bname, bname, snapshot, bname);
  288. eval_as_new_xact(rule_buf);
  289. sprintf(rule_buf,
  290. "define rewrite rule %s_replace3 is on replace to %s do insteadn
  291.     append %s_added(%s) from _%s in %s%s 
  292.     where current.oid !!= '%s_added.oid' and current.oid = 
  293.     _%s.oidn",
  294. vname, vname, vname, attr_list, bname, bname, snapshot, vname, bname);
  295. eval_as_new_xact(rule_buf);
  296. #endif  /* OLD_REWRITE */
  297. /* printf("%sn",rule_buf); */
  298. }
  299. #endif