version.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:10k
- /*-------------------------------------------------------------------------
- *
- * version.c
- * This file contains all the rules that govern all version semantics.
- *
- * Copyright (c) 1994, Regents of the University of California
- *
- * The version stuff has not been tested under postgres95 and probably
- * doesn't work! - jolly 8/19/95
- *
- *
- * $Id: version.c,v 1.19.2.1 1999/08/02 05:57:02 scrappy Exp $
- *
- * NOTES
- * At the point the version is defined, 2 physical relations are created
- * <vname>_added and <vname>_deleted.
- *
- * In addition, 4 rules are defined which govern the semantics of
- * versions w.r.t retrieves, appends, replaces and deletes.
- *
- *-------------------------------------------------------------------------
- */
- #include "postgres.h"
- #define MAX_QUERY_LEN 1024
- char rule_buf[MAX_QUERY_LEN];
- /*
- * problem: the version system assumes that the rules it declares will
- * be fired in the order of declaration, it also assumes
- * goh's silly instead semantics. Unfortunately, it is a pain
- * to make the version system work with the new semantics.
- * However the whole problem can be solved, and some nice
- * functionality can be achieved if we get multiple action rules
- * to work. So thats what I did -- glass
- *
- * Well, at least they've been working for about 20 minutes.
- *
- * So any comments in this code about 1 rule per transction are false...:)
- *
- */
- /*
- * This is needed because the rule system only allows
- * *1* rule to be defined per transaction.
- *
- * NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- *
- * DONT DO THAT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- *
- * If you commit the current Xact all the palloced memory GOES AWAY
- * and could be re-palloced in the new Xact and the whole hell breaks
- * loose and poor people like me spend 2 hours of their live chassing
- * a strange memory bug instead of watching the "Get Smart" marathon
- * in NICK !
- * DO NOT COMMIT THE XACT, just increase the Cid counter!
- * _sp.
- */
- #ifdef NOT_USED
- static void
- eval_as_new_xact(char *query)
- {
- /*
- * WARNING! do not uncomment the following lines WARNING!
- * CommitTransactionCommand(); StartTransactionCommand();
- */
- CommandCounterIncrement();
- pg_exec_query(query);
- }
- #endif
- /*
- * Define a version.
- */
- #ifdef NOT_USED
- void
- DefineVersion(char *name, char *fromRelname, char *date)
- {
- char *bname;
- static char saved_basename[512];
- static char saved_snapshot[512];
- if (date == NULL)
- {
- /* no time ranges */
- bname = fromRelname;
- strcpy(saved_basename, (char *) bname);
- *saved_snapshot = (char) NULL;
- }
- else
- {
- /* version is a snapshot */
- bname = fromRelname;
- strcpy(saved_basename, (char *) bname);
- sprintf(saved_snapshot, "['%s']", date);
- }
- /*
- * Calls the routine ``GetAttrList'' get the list of attributes from
- * the base relation. Code is put here so that we only need to look up
- * the attribute once for both appends and replaces.
- */
- setAttrList(bname);
- VersionCreate(name, saved_basename);
- VersionAppend(name, saved_basename);
- VersionDelete(name, saved_basename, saved_snapshot);
- VersionReplace(name, saved_basename, saved_snapshot);
- VersionRetrieve(name, saved_basename, saved_snapshot);
- }
- #endif
- /*
- * Creates the deltas.
- */
- #ifdef NOT_USED
- void
- VersionCreate(char *vname, char *bname)
- {
- static char query_buf[MAX_QUERY_LEN];
- /*
- * Creating the dummy version relation for triggering rules.
- */
- sprintf(query_buf, "SELECT * INTO TABLE %s from %s where 1 =2",
- vname, bname);
- pg_exec_query(query_buf);
- /*
- * Creating the ``v_added'' relation
- */
- sprintf(query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
- vname, bname);
- eval_as_new_xact(query_buf);
- /*
- * Creating the ``v_deleted'' relation.
- */
- sprintf(query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
- eval_as_new_xact(query_buf);
- }
- #endif
- /*
- * Given the relation name, does a catalog lookup for that relation and
- * sets the global variable 'attr_list' with the list of attributes (names)
- * for that relation.
- */
- #ifdef NOT_USED
- static void
- setAttrList(char *bname)
- {
- Relation rel;
- int i = 0;
- int maxattrs = 0;
- char *attrname;
- char temp_buf[512];
- int notfirst = 0;
- rel = heap_openr(bname);
- if (rel == NULL)
- {
- elog(ERROR, "Unable to expand all -- amopenr failed ");
- return;
- }
- maxattrs = RelationGetNumberOfAttributes(rel);
- attr_list[0] = ' ';
- for (i = maxattrs - 1; i > -1; --i)
- {
- attrname = (rel->rd_att->attrs[i]->attname).data;
- if (notfirst == 1)
- sprintf(temp_buf, ", %s = new.%s", attrname, attrname);
- else
- {
- sprintf(temp_buf, "%s = new.%s", attrname, attrname);
- notfirst = 1;
- }
- strcat(attr_list, temp_buf);
- }
- heap_close(rel);
- return;
- }
- #endif
- /*
- * This routine defines the rule governing the append semantics of
- * versions. All tuples appended to a version gets appended to the
- * <vname>_added relation.
- */
- #ifdef NOT_USED
- static void
- VersionAppend(char *vname, char *bname)
- {
- sprintf(rule_buf,
- "define rewrite rule %s_append is on INSERT to %s do instead append %s_added(%s)",
- vname, vname, vname, attr_list);
- eval_as_new_xact(rule_buf);
- }
- #endif
- /*
- * This routine defines the rule governing the retrieval semantics of
- * versions. To retrieve tuples from a version , we need to:
- *
- * 1. Retrieve all tuples in the <vname>_added relation.
- * 2. Retrieve all tuples in the base relation which are not in
- * the <vname>_del relation.
- */
- #ifdef NOT_USED
- void
- VersionRetrieve(char *vname, char *bname, char *snapshot)
- {
- sprintf(rule_buf,
- "define rewrite rule %s_retrieve is on SELECT to %s do insteadn
- SELECT %s_1.oid, %s_1.* from _%s in %s%s, %s_1 in (%s_added | _%s)
- where _%s.oid !!= '%s_del.DOID'",
- vname, vname, vname, vname, bname,
- bname, snapshot,
- vname, vname, bname, bname, vname);
- eval_as_new_xact(rule_buf);
- /* printf("%sn",rule_buf); */
- }
- #endif
- /*
- * This routine defines the rules that govern the delete semantics of
- * versions. Two things happens when we delete a tuple from a version:
- *
- * 1. If the tuple to be deleted was added to the version *after*
- * the version was created, then we simply delete the tuple
- * from the <vname>_added relation.
- * 2. If the tuple to be deleted is actually in the base relation,
- * then we have to mark that tuple as being deleted by adding
- * it to the <vname>_del relation.
- */
- #ifdef NOT_USED
- void
- VersionDelete(char *vname, char *bname, char *snapshot)
- {
- sprintf(rule_buf,
- "define rewrite rule %s_delete1 is on delete to %s do insteadn
- [delete %s_added where current.oid = %s_added.oidn
- append %s_del(DOID = current.oid) from _%s in %s%s
- where current.oid = _%s.oid] n",
- vname, vname, vname, vname, vname,
- bname, bname, snapshot, bname);
- eval_as_new_xact(rule_buf);
- #ifdef OLD_REWRITE
- sprintf(rule_buf,
- "define rewrite rule %s_delete2 is on delete to %s do instead n
- append %s_del(DOID = current.oid) from _%s in %s%s
- where current.oid = _%s.oid n",
- vname, vname, vname, bname, bname, snapshot, bname);
- eval_as_new_xact(rule_buf);
- #endif /* OLD_REWRITE */
- }
- #endif
- /*
- * This routine defines the rules that govern the update semantics
- * of versions. To update a tuple in a version:
- *
- * 1. If the tuple is in <vname>_added, we simply ``replace''
- * the tuple (as per postgres style).
- * 2. if the tuple is in the base relation, then two things have to
- * happen:
- * 2.1 The tuple is marked ``deleted'' from the base relation by
- * adding the tuple to the <vname>_del relation.
- * 2.2 A copy of the tuple is appended to the <vname>_added relation
- */
- #ifdef NOT_USED
- void
- VersionReplace(char *vname, char *bname, char *snapshot)
- {
- sprintf(rule_buf,
- "define rewrite rule %s_replace1 is on replace to %s do instead n
- [replace %s_added(%s) where current.oid = %s_added.oid n
- append %s_del(DOID = current.oid) from _%s in %s%s
- where current.oid = _%s.oidn
- append %s_added(%s) from _%s in %s%s
- where current.oid !!= '%s_added.oid' and current.oid = _%s.oid]n",
- vname, vname, vname, attr_list, vname,
- vname, bname, bname, snapshot, bname,
- vname, attr_list, bname, bname, snapshot, vname, bname);
- eval_as_new_xact(rule_buf);
- /* printf("%sn",rule_buf); */
- #ifdef OLD_REWRITE
- sprintf(rule_buf,
- "define rewrite rule %s_replace2 is on replace to %s do n
- append %s_del(DOID = current.oid) from _%s in %s%s
- where current.oid = _%s.oidn",
- vname, vname, vname, bname, bname, snapshot, bname);
- eval_as_new_xact(rule_buf);
- sprintf(rule_buf,
- "define rewrite rule %s_replace3 is on replace to %s do insteadn
- append %s_added(%s) from _%s in %s%s
- where current.oid !!= '%s_added.oid' and current.oid =
- _%s.oidn",
- vname, vname, vname, attr_list, bname, bname, snapshot, vname, bname);
- eval_as_new_xact(rule_buf);
- #endif /* OLD_REWRITE */
- /* printf("%sn",rule_buf); */
- }
- #endif