1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-18 17:42:25 +03:00

Postgres95 1.01 Distribution - Virgin Sources

This commit is contained in:
Marc G. Fournier
1996-07-09 06:22:35 +00:00
commit d31084e9d1
868 changed files with 242656 additions and 0 deletions
src
MakefileMakefile.global
backend
Makefile
access
bootstrap
catalog
commands
executor
include
lib
libpq
main
makeID
nodes
optimizer
parser
port
postmaster
regex
rewrite
storage
tcop
tioga
utils
bin
interfaces
mk
test
tools
tutorial

@ -0,0 +1,270 @@
/*-------------------------------------------------------------------------
*
* rewriteSupport.c--
*
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.1.1.1 1996/07/09 06:21:52 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/catname.h"
#include "catalog/pg_rewrite.h"
#include "utils/syscache.h" /* for SearchSysCache */
#include "nodes/pg_list.h"
#include "nodes/parsenodes.h"
#include "utils/builtins.h" /* for textout */
#include "utils/rel.h" /* for Relation, RelationData ... */
#include "utils/elog.h" /* for elog */
#include "storage/buf.h" /* for InvalidBuffer */
#include "rewrite/rewriteSupport.h"
#include "access/heapam.h"
#include "catalog/pg_class.h"
#include "catalog/pg_proc.h"
#include "catalog/indexing.h"
#include "utils/catcache.h" /* for CacheContext */
#include "utils/mcxt.h" /* MemoryContext stuff */
#include "utils/palloc.h"
#include "fmgr.h"
/*
* RuleIdGetActionInfo -
* given a rule oid, look it up and return the rule-event-qual and
* list of parsetrees for the rule (in parseTrees)
*/
static Node *
RuleIdGetActionInfo(Oid ruleoid, bool *instead_flag, Query **parseTrees)
{
HeapTuple ruletuple;
char *ruleaction = NULL;
bool action_is_null = false;
bool instead_is_null = false;
Relation ruleRelation = NULL;
TupleDesc ruleTupdesc = NULL;
Query *ruleparse = NULL;
char *rule_evqual_string = NULL;
Node *rule_evqual = NULL;
ruleRelation = heap_openr (RewriteRelationName);
ruleTupdesc = RelationGetTupleDescriptor(ruleRelation);
ruletuple = SearchSysCacheTuple (RULOID,
ObjectIdGetDatum(ruleoid),
0,0,0);
if (ruletuple == NULL)
elog(WARN, "rule %d isn't in rewrite system relation");
ruleaction = heap_getattr(ruletuple,
InvalidBuffer,
Anum_pg_rewrite_action,
ruleTupdesc,
&action_is_null ) ;
rule_evqual_string = heap_getattr(ruletuple, InvalidBuffer,
Anum_pg_rewrite_ev_qual,
ruleTupdesc, &action_is_null) ;
*instead_flag = (bool) heap_getattr(ruletuple, InvalidBuffer,
Anum_pg_rewrite_is_instead,
ruleTupdesc, &instead_is_null) ;
if (action_is_null || instead_is_null) {
elog(WARN, "internal error: rewrite rule not properly set up");
}
ruleaction = textout((struct varlena *)ruleaction);
rule_evqual_string = textout((struct varlena *)rule_evqual_string);
ruleparse = (Query*)stringToNode(ruleaction);
rule_evqual = (Node*)stringToNode(rule_evqual_string);
heap_close(ruleRelation);
*parseTrees = ruleparse;
return rule_evqual;
}
int
IsDefinedRewriteRule(char *ruleName)
{
Relation RewriteRelation = NULL;
HeapScanDesc scanDesc = NULL;
ScanKeyData scanKey;
HeapTuple tuple = NULL;
/*
* Open the pg_rewrite relation.
*/
RewriteRelation = heap_openr(RewriteRelationName);
/*
* Scan the RuleRelation ('pg_rewrite') until we find a tuple
*/
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_rewrite_rulename,
NameEqualRegProcedure, PointerGetDatum(ruleName));
scanDesc = heap_beginscan(RewriteRelation,
0, NowTimeQual, 1, &scanKey);
tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
/*
* return whether or not the rewrite rule existed
*/
heap_close(RewriteRelation);
heap_endscan(scanDesc);
return (HeapTupleIsValid(tuple));
}
static void
setRelhasrulesInRelation(Oid relationId, bool relhasrules)
{
Relation relationRelation;
HeapTuple tuple;
HeapTuple newTuple;
Relation idescs[Num_pg_class_indices];
Form_pg_class relp;
/*
* Lock a relation given its Oid.
* Go to the RelationRelation (i.e. pg_relation), find the
* appropriate tuple, and add the specified lock to it.
*/
relationRelation = heap_openr(RelationRelationName);
tuple = ClassOidIndexScan(relationRelation, relationId);
/*
* Create a new tuple (i.e. a copy of the old tuple
* with its rule lock field changed and replace the old
* tuple in the RelationRelation
* NOTE: XXX ??? do we really need to make that copy ????
*/
newTuple = heap_copytuple(tuple);
relp = (Form_pg_class) GETSTRUCT(newTuple);
relp->relhasrules = relhasrules;
(void) heap_replace(relationRelation, &(tuple->t_ctid), newTuple);
/* keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation,
newTuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
/* be tidy */
pfree(tuple);
pfree(newTuple);
heap_close(relationRelation);
}
void
prs2_addToRelation(Oid relid,
Oid ruleId,
CmdType event_type,
AttrNumber attno,
bool isInstead,
Node *qual,
List *actions)
{
Relation relation;
RewriteRule *thisRule;
RuleLock *rulelock;
MemoryContext oldcxt;
/*
* create an in memory RewriteRule data structure which is cached by
* every Relation descriptor. (see utils/cache/relcache.c)
*/
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
thisRule = (RewriteRule *)palloc(sizeof(RewriteRule));
MemoryContextSwitchTo(oldcxt);
thisRule->ruleId = ruleId;
thisRule->event = event_type;
thisRule->attrno = attno;
thisRule->qual = qual;
thisRule->actions = actions;
thisRule->isInstead = isInstead;
relation = heap_open(relid);
/*
* modify or create a RuleLock cached by Relation
*/
if (relation->rd_rules == NULL) {
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
rulelock = (RuleLock *)palloc(sizeof(RuleLock));
rulelock->numLocks = 1;
rulelock->rules = (RewriteRule **)palloc(sizeof(RewriteRule*));
rulelock->rules[0] = thisRule;
relation->rd_rules = rulelock;
MemoryContextSwitchTo(oldcxt);
/*
* the fact that relation->rd_rules is NULL means the relhasrules
* attribute of the tuple of this relation in pg_class is false. We
* need to set it to true.
*/
setRelhasrulesInRelation(relid, TRUE);
} else {
int numlock;
rulelock = relation->rd_rules;
numlock = rulelock->numLocks;
/* expand, for safety reasons */
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
rulelock->rules =
(RewriteRule **)repalloc(rulelock->rules,
sizeof(RewriteRule*)*(numlock+1));
MemoryContextSwitchTo(oldcxt);
rulelock->rules[numlock] = thisRule;
rulelock->numLocks++;
}
heap_close(relation);
return;
}
void
prs2_deleteFromRelation(Oid relid, Oid ruleId)
{
RuleLock *rulelock;
Relation relation;
int numlock;
int i;
MemoryContext oldcxt;
relation = heap_open(relid);
rulelock = relation->rd_rules;
Assert(rulelock != NULL);
numlock = rulelock->numLocks;
for(i=0; i < numlock; i++) {
if (rulelock->rules[i]->ruleId == ruleId)
break;
}
Assert(i<numlock);
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
pfree(rulelock->rules[i]);
MemoryContextSwitchTo(oldcxt);
if (numlock==1) {
relation->rd_rules = NULL;
/*
* we don't have rules any more, flag the relhasrules attribute of
* the tuple of this relation in pg_class false.
*/
setRelhasrulesInRelation(relid, FALSE);
} else {
rulelock->rules[i] = rulelock->rules[numlock-1];
rulelock->rules[numlock-1] = NULL;
rulelock->numLocks--;
}
heap_close(relation);
}