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:
src
MakefileMakefile.global
backend
Makefile
access
Makefile.incattnum.h
common
funcindex.hgenam.hhash.hhash
Makefile.inchash.chashfunc.chashinsert.chashovfl.chashpage.chashscan.chashsearch.chashstrat.chashutil.c
heap
heapam.hhio.hhtup.hibit.hindex
iqual.histrat.hitup.hnbtree.hnbtree
Makefile.incREADMEnbtcompare.cnbtinsert.cnbtpage.cnbtree.cnbtscan.cnbtsearch.cnbtsort.cnbtstrat.cnbtutils.c
printtup.hrelscan.hrtree.hrtree
rtscan.hrtstrat.hsdir.hskey.hstrat.htransam.htransam
tupdesc.htupmacs.hvalid.hxact.hbootstrap
catalog
Makefile.incREADMEcatalog.ccatalog.hcatname.hgenbki.shheap.cheap.hindex.cindex.hindexing.cindexing.hpg_aggregate.cpg_aggregate.hpg_am.hpg_amop.hpg_amproc.hpg_attribute.hpg_class.hpg_database.hpg_defaults.hpg_demon.hpg_group.hpg_hosts.hpg_index.hpg_inheritproc.hpg_inherits.hpg_ipl.hpg_language.hpg_listener.hpg_log.hpg_magic.hpg_opclass.hpg_operator.cpg_operator.hpg_parg.hpg_proc.cpg_proc.hpg_rewrite.hpg_server.hpg_statistic.hpg_time.hpg_type.cpg_type.hpg_user.hpg_variable.hpg_version.hunused_oids
commands
Makefile.inc
_deadcode
async.casync.hcluster.ccluster.hcommand.ccommand.hcopy.ccopy.hcreatinh.ccreatinh.hdefind.cdefine.cdefrem.hexplain.cexplain.hpurge.cpurge.hrecipe.crecipe.hremove.crename.crename.hvacuum.cvacuum.hversion.hview.cview.hexecutor
Makefile.incexecAmi.cexecFlatten.cexecFlatten.hexecJunk.cexecMain.cexecProcnode.cexecQual.cexecScan.cexecTuples.cexecUtils.cexecdebug.hexecdefs.hexecdesc.hexecutor.hfunctions.cfunctions.hhashjoin.hnodeAgg.cnodeAgg.hnodeAppend.cnodeAppend.hnodeGroup.cnodeGroup.hnodeHash.cnodeHash.hnodeHashjoin.cnodeHashjoin.hnodeIndexscan.cnodeIndexscan.hnodeMaterial.cnodeMaterial.hnodeMergejoin.cnodeMergejoin.hnodeNestloop.cnodeNestloop.hnodeResult.cnodeResult.hnodeSeqscan.cnodeSeqscan.hnodeSort.cnodeSort.hnodeTee.cnodeTee.hnodeUnique.cnodeUnique.htuptable.h
include
lib
Makefile.incbit.cdllist.cdllist.hfstack.cfstack.hhasht.chasht.hlispsort.clispsort.hqsort.cqsort.hstringinfo.cstringinfo.h
libpq
Makefile.incauth.cauth.hbe-dumpdata.cbe-fsstubs.cbe-fsstubs.hbe-pqexec.clibpq-be.hlibpq-fs.hlibpq.hportal.cportalbuf.cpqcomm.cpqcomm.hpqpacket.cpqsignal.cpqsignal.h
main
makeIDnodes
Makefile.incREADMEcopyfuncs.cequalfuncs.cexecnodes.hlist.cmakefuncs.cmakefuncs.hmemnodes.hnodeFuncs.cnodeFuncs.hnodes.cnodes.houtfuncs.cparams.hparsenodes.hpg_list.hplannodes.hprimnodes.hprint.cread.creadfuncs.creadfuncs.hrelation.h
optimizer
Makefile.incclauseinfo.hclauses.hcost.hinternal.hjoininfo.hkeys.hordering.h
path
Makefile.incallpaths.cclausesel.ccostsize.chashutils.cindxpath.cjoinpath.cjoinrels.cjoinutils.cmergeutils.corindxpath.cpredmig.cprune.cxfunc.c
pathnode.hpaths.hplan
plancat.hplanmain.hplanner.hprep.hprep
tlist.hutil
Makefile.incclauseinfo.cclauses.cindexnode.cinternal.cjoininfo.ckeys.cordering.cpathnode.cplancat.crelnode.ctlist.cvar.c
var.hxfunc.hparser
Makefile.incanalyze.ccatalog_utils.ccatalog_utils.hdbcommands.cdbcommands.hgram.ykeywords.ckeywords.hparse_query.cparse_query.hparse_state.hparser.cparsetree.hscan.lscansup.cscansup.h
port
postmaster
regex
COPYRIGHTMakefile.incWHATSNEWcclass.hcdefs.hcname.hengine.cre_format.7regcomp.cregerror.cregex.3regex.hregex2.hregexec.cregexp.hregfree.cutils.h
rewrite
Makefile.inclocks.clocks.hprs2lock.hrewriteDefine.crewriteDefine.hrewriteHandler.crewriteHandler.hrewriteManip.crewriteManip.hrewriteRemove.crewriteRemove.hrewriteSupport.crewriteSupport.h
storage
Makefile.incbackendid.hblock.hbuf.hbuf_internals.h
buffer
bufmgr.hbufpage.hfd.hfile
ipc.hipc
item.hitemid.hitempos.hitemptr.hlarge_object.hlarge_object
lmgr.hlmgr
lock.hmultilev.hoff.hpage.hpage
pagenum.hpos.hproc.hshmem.hsinval.hsinvaladt.hsmgr.hsmgr
spin.htcop
Makefile.incaclchk.cdest.cdest.hfastpath.cfastpath.hpostgres.cpquery.cpquery.htcopdebug.htcopprot.hutility.cutility.h
tioga
utils
Gen_fmgrtab.shMakefile.incacl.h
adt
Makefile.incacl.carrayfuncs.carrayutils.cbool.cchar.cchunk.cdate.cdatetimes.cdatum.cdt.cfilename.cfloat.cgeo-ops.cgeo-selfuncs.cint.clike.cmisc.cnabstime.cname.cnot_in.cnumutils.coid.coidint2.coidint4.coidname.cregexp.cregproc.cselfuncs.csets.ctid.cvarchar.cvarlena.c
array.hbit.hbuiltins.hcache
catcache.hdatum.hdynamic_loader.helog.herror
exc.hexcid.hfcache.hfcache2.hfmgr
fmgrtab.hgeo-decls.hhash
hsearch.hinit
inval.hlselect.hlsyscache.hmcxt.hmemutils.hmmgr
module.hnabstime.hoidcompos.hpalloc.hportal.hpsort.hrel.hrel2.hrelcache.hsets.hsort
syscache.htime
tqual.hbin
MakefileMakefile.global
cleardbdir
createdb
createuser
destroydb
destroyuser
initdb
ipcclean
monitor
pg4_dump
pg_dump
pg_id
pg_version
pgtclsh
psql
interfaces
libpgtcl
libpq++
MakefileREADME
examples
Makefiletestlibpq0.cctestlibpq1.cctestlibpq2.cctestlibpq2.sqltestlibpq3.cctestlibpq3.sqltestlibpq4.cctestlo.cc
libpq++.Hman
pgconnection.ccpgenv.ccpglobject.cclibpq
mk
port
postgres.mk.BSD44_derivedpostgres.mk.aixpostgres.mk.alphapostgres.mk.bsdipostgres.mk.hpuxpostgres.mk.irix5postgres.mk.linuxpostgres.mk.sparcpostgres.mk.sparc_solarispostgres.mk.svr4postgres.mk.ultrix4
postgres.lib.mkpostgres.mkpostgres.prog.mkpostgres.shell.mkpostgres.subdir.mkpostgres.user.mktest
Makefile
bench
MakefileWISC-READMEcreate.shcreate.sourceperqueryquery01query02query03query04query05query06query07query08query09query10query11query12query13query14query15query16query17query18query19query20query21query22query23query24query25query26query27query28query29query30query31query32runwisc.shwholebench.sh
examples
Makefiletestlibpq.ctestlibpq2.ctestlibpq2.sqltestlibpq3.ctestlibpq3.sqltestlibpq4.ctestlo.ctestlo2.c
regress
Makefilecreate.source
data
dept.datadesc.dataemp.datahash.dataonek.dataperson.datareal_city.datarect.datastreets.datastud_emp.datastudent.datatenk.data
destroy.sourceerrors.sourcequeries.sourceregress.cregress.shsample.regress.outsecurity.sourcesuite
READMEagg.sqldate.sqlfloat.sqlgroup.sqlgroup_err.sqlinh.sqljoin.sqloper.sqlparse.sqlquote.sql
results
agg.sql.outdate.sql.outfloat.sql.outgroup.sql.outgroup_err.sql.outinh.sql.outjoin.sql.outoper.sql.outparse.sql.outquote.sql.outrules.sql.outselect.sql.outsort.sql.outsqlcompat.sql.outtime.sql.outvarchar.sql.outviews.sql.out
rules.sqlrunallselect.sqlsort.sqlsqlcompat.sqltime.sqlvarchar.sqlviews.sqltools
mkldexport
tutorial
270
src/backend/rewrite/rewriteSupport.c
Normal file
270
src/backend/rewrite/rewriteSupport.c
Normal file
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user