mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
OK, folks, here is the pgindent output.
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.12 1998/09/01 03:24:53 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.13 1998/09/01 04:31:30 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -175,12 +175,12 @@ checkLockPerms(List *locks, Query *parsetree, int rt_index)
|
||||
{
|
||||
Relation ev_rel;
|
||||
HeapTuple usertup;
|
||||
char *evowner;
|
||||
RangeTblEntry *rte;
|
||||
char *evowner;
|
||||
RangeTblEntry *rte;
|
||||
int32 reqperm;
|
||||
int32 aclcheck_res;
|
||||
int i;
|
||||
List *l;
|
||||
int i;
|
||||
List *l;
|
||||
|
||||
if (locks == NIL)
|
||||
return;
|
||||
@ -188,11 +188,11 @@ checkLockPerms(List *locks, Query *parsetree, int rt_index)
|
||||
/*
|
||||
* Get the usename of the rules event relation owner
|
||||
*/
|
||||
rte = (RangeTblEntry *)nth(rt_index - 1, parsetree->rtable);
|
||||
rte = (RangeTblEntry *) nth(rt_index - 1, parsetree->rtable);
|
||||
ev_rel = heap_openr(rte->relname);
|
||||
usertup = SearchSysCacheTuple(USESYSID,
|
||||
ObjectIdGetDatum(ev_rel->rd_rel->relowner),
|
||||
0, 0, 0);
|
||||
ObjectIdGetDatum(ev_rel->rd_rel->relowner),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(usertup))
|
||||
{
|
||||
elog(ERROR, "cache lookup for userid %d failed",
|
||||
@ -200,29 +200,32 @@ checkLockPerms(List *locks, Query *parsetree, int rt_index)
|
||||
}
|
||||
heap_close(ev_rel);
|
||||
evowner = nameout(&(((Form_pg_shadow) GETSTRUCT(usertup))->usename));
|
||||
|
||||
|
||||
/*
|
||||
* Check all the locks, that should get fired on this query
|
||||
*/
|
||||
foreach (l, locks) {
|
||||
RewriteRule *onelock = (RewriteRule *)lfirst(l);
|
||||
List *action;
|
||||
foreach(l, locks)
|
||||
{
|
||||
RewriteRule *onelock = (RewriteRule *) lfirst(l);
|
||||
List *action;
|
||||
|
||||
/*
|
||||
* In each lock check every action
|
||||
*/
|
||||
foreach (action, onelock->actions) {
|
||||
Query *query = (Query *)lfirst(action);
|
||||
foreach(action, onelock->actions)
|
||||
{
|
||||
Query *query = (Query *) lfirst(action);
|
||||
|
||||
/*
|
||||
* In each action check every rangetable entry
|
||||
* for read/write permission of the event relations
|
||||
* owner depending on if it's the result relation
|
||||
* (write) or not (read)
|
||||
* In each action check every rangetable entry for read/write
|
||||
* permission of the event relations owner depending on if
|
||||
* it's the result relation (write) or not (read)
|
||||
*/
|
||||
for (i = 2; i < length(query->rtable); i++) {
|
||||
for (i = 2; i < length(query->rtable); i++)
|
||||
{
|
||||
if (i + 1 == query->resultRelation)
|
||||
switch (query->resultRelation) {
|
||||
switch (query->resultRelation)
|
||||
{
|
||||
case CMD_INSERT:
|
||||
reqperm = ACL_AP;
|
||||
break;
|
||||
@ -233,19 +236,19 @@ checkLockPerms(List *locks, Query *parsetree, int rt_index)
|
||||
else
|
||||
reqperm = ACL_RD;
|
||||
|
||||
rte = (RangeTblEntry *)nth(i, query->rtable);
|
||||
aclcheck_res = pg_aclcheck(rte->relname,
|
||||
evowner, reqperm);
|
||||
if (aclcheck_res != ACLCHECK_OK) {
|
||||
elog(ERROR, "%s: %s",
|
||||
rte->relname,
|
||||
aclcheck_error_strings[aclcheck_res]);
|
||||
rte = (RangeTblEntry *) nth(i, query->rtable);
|
||||
aclcheck_res = pg_aclcheck(rte->relname,
|
||||
evowner, reqperm);
|
||||
if (aclcheck_res != ACLCHECK_OK)
|
||||
{
|
||||
elog(ERROR, "%s: %s",
|
||||
rte->relname,
|
||||
aclcheck_error_strings[aclcheck_res]);
|
||||
}
|
||||
|
||||
/*
|
||||
* So this is allowed due to the permissions
|
||||
* of the rules event relation owner. But
|
||||
* let's see if the next one too
|
||||
* So this is allowed due to the permissions of the rules
|
||||
* event relation owner. But let's see if the next one too
|
||||
*/
|
||||
rte->skipAcl = TRUE;
|
||||
}
|
||||
@ -257,5 +260,3 @@ checkLockPerms(List *locks, Query *parsetree, int rt_index)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.20 1998/09/01 03:24:54 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.21 1998/09/01 04:31:32 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -156,6 +156,7 @@ ValidateRule(int event_type,
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* on retrieve to class.attribute do instead nothing is converted to
|
||||
* 'on retrieve to class.attribute do instead retrieve (attribute =
|
||||
@ -200,51 +201,55 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||
* rules only. And for SELECT events, it expects one non-nothing
|
||||
* action that is instead. Since we now hand out views and rules
|
||||
* to regular users, we must deny anything else.
|
||||
*
|
||||
*
|
||||
* I know that I must write a new rewrite handler from scratch
|
||||
* for 6.5 so we can remove these checks and allow all the rules.
|
||||
*
|
||||
* Jan
|
||||
* Jan
|
||||
* ----------
|
||||
*/
|
||||
if (event_obj->attrs)
|
||||
elog(ERROR, "attribute level rules currently not supported");
|
||||
/*
|
||||
eslot_string = strVal(lfirst(event_obj->attrs));
|
||||
*/
|
||||
|
||||
/*
|
||||
* eslot_string = strVal(lfirst(event_obj->attrs));
|
||||
*/
|
||||
else
|
||||
eslot_string = NULL;
|
||||
|
||||
if (action != NIL)
|
||||
foreach (l, action) {
|
||||
query = (Query *)lfirst(l);
|
||||
if (query->resultRelation == 1) {
|
||||
elog(NOTICE, "rule actions on OLD currently not supported");
|
||||
elog(ERROR, " use views or triggers instead");
|
||||
}
|
||||
if (query->resultRelation == 2) {
|
||||
elog(NOTICE, "rule actions on NEW currently not supported");
|
||||
elog(ERROR, " use triggers instead");
|
||||
}
|
||||
foreach(l, action)
|
||||
{
|
||||
query = (Query *) lfirst(l);
|
||||
if (query->resultRelation == 1)
|
||||
{
|
||||
elog(NOTICE, "rule actions on OLD currently not supported");
|
||||
elog(ERROR, " use views or triggers instead");
|
||||
}
|
||||
if (query->resultRelation == 2)
|
||||
{
|
||||
elog(NOTICE, "rule actions on NEW currently not supported");
|
||||
elog(ERROR, " use triggers instead");
|
||||
}
|
||||
}
|
||||
|
||||
if (event_type == CMD_SELECT) {
|
||||
if (length(action) == 0) {
|
||||
if (event_type == CMD_SELECT)
|
||||
{
|
||||
if (length(action) == 0)
|
||||
{
|
||||
elog(NOTICE, "instead nothing rules on select currently not supported");
|
||||
elog(ERROR, " use views instead");
|
||||
}
|
||||
if (length(action) > 1) {
|
||||
if (length(action) > 1)
|
||||
elog(ERROR, "multiple action rules on select currently not supported");
|
||||
}
|
||||
query = (Query *)lfirst(action);
|
||||
if (!is_instead || query->commandType != CMD_SELECT) {
|
||||
query = (Query *) lfirst(action);
|
||||
if (!is_instead || query->commandType != CMD_SELECT)
|
||||
elog(ERROR, "only instead-select rules currently supported on select");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This rule is currently allowed - too restricted I know -
|
||||
* but women and children first
|
||||
* Jan
|
||||
* This rule is currently allowed - too restricted I know - but women
|
||||
* and children first Jan
|
||||
*/
|
||||
|
||||
event_relation = heap_openr(event_obj->relname);
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.20 1998/08/24 01:37:59 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.21 1998/09/01 04:31:33 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -35,12 +35,10 @@
|
||||
#include "utils/acl.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
|
||||
static void
|
||||
ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
|
||||
static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
|
||||
int rt_index, int relation_level,
|
||||
Relation relation, int *modified);
|
||||
static List *
|
||||
fireRules(Query *parsetree, int rt_index, CmdType event,
|
||||
static List *fireRules(Query *parsetree, int rt_index, CmdType event,
|
||||
bool *instead_flag, List *locks, List **qual_products);
|
||||
static void QueryRewriteSubLink(Node *node);
|
||||
static List *QueryRewriteOne(Query *parsetree);
|
||||
@ -146,21 +144,23 @@ OptimizeRIRRules(List *locks)
|
||||
static List *
|
||||
orderRules(List *locks)
|
||||
{
|
||||
List *regular = NIL;
|
||||
List *instead_rules = NIL;
|
||||
List *instead_qualified = NIL;
|
||||
List *i;
|
||||
List *regular = NIL;
|
||||
List *instead_rules = NIL;
|
||||
List *instead_qualified = NIL;
|
||||
List *i;
|
||||
|
||||
foreach(i, locks)
|
||||
{
|
||||
RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
|
||||
|
||||
if (rule_lock->isInstead) {
|
||||
if (rule_lock->isInstead)
|
||||
{
|
||||
if (rule_lock->qual == NULL)
|
||||
instead_rules = lappend(instead_rules, rule_lock);
|
||||
else
|
||||
instead_qualified = lappend(instead_qualified, rule_lock);
|
||||
} else
|
||||
}
|
||||
else
|
||||
regular = lappend(regular, rule_lock);
|
||||
}
|
||||
regular = nconc(regular, instead_qualified);
|
||||
@ -202,7 +202,7 @@ FireRetrieveRulesAtQuery(Query *parsetree,
|
||||
if ((rt_entry_locks = relation->rd_rules) == NULL)
|
||||
return NIL;
|
||||
|
||||
locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
|
||||
locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
|
||||
|
||||
/* find all retrieve instead */
|
||||
foreach(i, locks)
|
||||
@ -313,7 +313,7 @@ ApplyRetrieveRule(Query *parsetree,
|
||||
OffsetVarNodes(rule_action->qual, rt_length);
|
||||
OffsetVarNodes((Node *) rule_action->targetList, rt_length);
|
||||
OffsetVarNodes(rule_qual, rt_length);
|
||||
|
||||
|
||||
OffsetVarNodes((Node *) rule_action->groupClause, rt_length);
|
||||
OffsetVarNodes((Node *) rule_action->havingQual, rt_length);
|
||||
|
||||
@ -330,24 +330,29 @@ ApplyRetrieveRule(Query *parsetree,
|
||||
|
||||
if (relation_level)
|
||||
{
|
||||
HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
|
||||
modified);
|
||||
HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
|
||||
modified);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
|
||||
rt_index, rule->attrno, modified, &badsql);
|
||||
HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
|
||||
rt_index, rule->attrno, modified, &badsql);
|
||||
}
|
||||
if (*modified && !badsql)
|
||||
{
|
||||
AddQual(parsetree, rule_action->qual);
|
||||
|
||||
/*
|
||||
* This will only work if the query made to the view defined by
|
||||
* the following groupClause groups by the same attributes or does
|
||||
* not use group at all!
|
||||
*/
|
||||
if (parsetree->groupClause == NULL)
|
||||
parsetree->groupClause = rule_action->groupClause;
|
||||
AddHavingQual(parsetree, rule_action->havingQual);
|
||||
parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs);
|
||||
parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks);
|
||||
}
|
||||
if (*modified && !badsql) {
|
||||
AddQual(parsetree, rule_action->qual);
|
||||
/* This will only work if the query made to the view defined by the following
|
||||
* groupClause groups by the same attributes or does not use group at all! */
|
||||
if (parsetree->groupClause == NULL)
|
||||
parsetree->groupClause=rule_action->groupClause;
|
||||
AddHavingQual(parsetree, rule_action->havingQual);
|
||||
parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs);
|
||||
parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks);
|
||||
}
|
||||
}
|
||||
|
||||
static List *
|
||||
@ -382,9 +387,8 @@ ProcessRetrieveQuery(Query *parsetree,
|
||||
rule);
|
||||
}
|
||||
heap_close(rt_entry_relation);
|
||||
if (*instead_flag) {
|
||||
if (*instead_flag)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (rule)
|
||||
return NIL;
|
||||
@ -465,7 +469,7 @@ CopyAndAddQual(Query *parsetree,
|
||||
* with rule qualification save the original parsetree
|
||||
* and add their negated qualification to it. Real instead
|
||||
* rules finally throw away the original parsetree.
|
||||
*
|
||||
*
|
||||
* remember: reality is for dead birds -- glass
|
||||
*
|
||||
*/
|
||||
@ -504,22 +508,22 @@ fireRules(Query *parsetree,
|
||||
bool orig_instead_flag = *instead_flag;
|
||||
|
||||
/*
|
||||
* Instead rules change the resultRelation of the
|
||||
* query. So the permission checks on the initial
|
||||
* resultRelation would never be done (this is
|
||||
* normally done in the executor deep down). So
|
||||
* we must do it here. The result relations resulting
|
||||
* from earlier rewrites are already checked against
|
||||
* the rules eventrelation owner (during matchLocks)
|
||||
* and have the skipAcl flag set.
|
||||
* Instead rules change the resultRelation of the query. So the
|
||||
* permission checks on the initial resultRelation would never be
|
||||
* done (this is normally done in the executor deep down). So we
|
||||
* must do it here. The result relations resulting from earlier
|
||||
* rewrites are already checked against the rules eventrelation
|
||||
* owner (during matchLocks) and have the skipAcl flag set.
|
||||
*/
|
||||
if (rule_lock->isInstead &&
|
||||
parsetree->commandType != CMD_SELECT) {
|
||||
RangeTblEntry *rte;
|
||||
if (rule_lock->isInstead &&
|
||||
parsetree->commandType != CMD_SELECT)
|
||||
{
|
||||
RangeTblEntry *rte;
|
||||
int32 acl_rc;
|
||||
int32 reqperm;
|
||||
|
||||
switch (parsetree->commandType) {
|
||||
switch (parsetree->commandType)
|
||||
{
|
||||
case CMD_INSERT:
|
||||
reqperm = ACL_AP;
|
||||
break;
|
||||
@ -527,16 +531,18 @@ fireRules(Query *parsetree,
|
||||
reqperm = ACL_WR;
|
||||
break;
|
||||
}
|
||||
|
||||
rte = (RangeTblEntry *)nth(parsetree->resultRelation - 1,
|
||||
parsetree->rtable);
|
||||
if (!rte->skipAcl) {
|
||||
|
||||
rte = (RangeTblEntry *) nth(parsetree->resultRelation - 1,
|
||||
parsetree->rtable);
|
||||
if (!rte->skipAcl)
|
||||
{
|
||||
acl_rc = pg_aclcheck(rte->relname,
|
||||
GetPgUserName(), reqperm);
|
||||
if (acl_rc != ACLCHECK_OK) {
|
||||
GetPgUserName(), reqperm);
|
||||
if (acl_rc != ACLCHECK_OK)
|
||||
{
|
||||
elog(ERROR, "%s: %s",
|
||||
rte->relname,
|
||||
aclcheck_error_strings[acl_rc]);
|
||||
rte->relname,
|
||||
aclcheck_error_strings[acl_rc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -545,9 +551,10 @@ fireRules(Query *parsetree,
|
||||
*instead_flag = rule_lock->isInstead;
|
||||
event_qual = rule_lock->qual;
|
||||
actions = rule_lock->actions;
|
||||
if (event_qual != NULL && *instead_flag) {
|
||||
Query *qual_product;
|
||||
RewriteInfo qual_info;
|
||||
if (event_qual != NULL && *instead_flag)
|
||||
{
|
||||
Query *qual_product;
|
||||
RewriteInfo qual_info;
|
||||
|
||||
/* ----------
|
||||
* If there are instead rules with qualifications,
|
||||
@ -561,21 +568,20 @@ fireRules(Query *parsetree,
|
||||
* list after we mangled it up enough.
|
||||
* ----------
|
||||
*/
|
||||
if (*qual_products == NIL) {
|
||||
if (*qual_products == NIL)
|
||||
qual_product = parsetree;
|
||||
} else {
|
||||
qual_product = (Query *)nth(0, *qual_products);
|
||||
}
|
||||
else
|
||||
qual_product = (Query *) nth(0, *qual_products);
|
||||
|
||||
qual_info.event = qual_product->commandType;
|
||||
qual_info.new_varno = length(qual_product->rtable) + 2;
|
||||
qual_product = CopyAndAddQual(qual_product,
|
||||
actions,
|
||||
event_qual,
|
||||
rt_index,
|
||||
event);
|
||||
|
||||
qual_info.rule_action = qual_product;
|
||||
qual_info.event = qual_product->commandType;
|
||||
qual_info.new_varno = length(qual_product->rtable) + 2;
|
||||
qual_product = CopyAndAddQual(qual_product,
|
||||
actions,
|
||||
event_qual,
|
||||
rt_index,
|
||||
event);
|
||||
|
||||
qual_info.rule_action = qual_product;
|
||||
|
||||
if (event == CMD_INSERT || event == CMD_UPDATE)
|
||||
FixNew(&qual_info, qual_product);
|
||||
@ -658,9 +664,8 @@ fireRules(Query *parsetree,
|
||||
* throw away an eventually saved 'default' parsetree
|
||||
* ----------
|
||||
*/
|
||||
if (event_qual == NULL && *instead_flag) {
|
||||
if (event_qual == NULL && *instead_flag)
|
||||
*qual_products = NIL;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@ -682,19 +687,21 @@ RewritePreprocessQuery(Query *parsetree)
|
||||
* from the rewritten query.
|
||||
* ----------
|
||||
*/
|
||||
if (parsetree->resultRelation > 0) {
|
||||
RangeTblEntry *rte;
|
||||
if (parsetree->resultRelation > 0)
|
||||
{
|
||||
RangeTblEntry *rte;
|
||||
Relation rd;
|
||||
List *tl;
|
||||
TargetEntry *tle;
|
||||
int resdomno;
|
||||
|
||||
rte = (RangeTblEntry *)nth(parsetree->resultRelation - 1,
|
||||
parsetree->rtable);
|
||||
List *tl;
|
||||
TargetEntry *tle;
|
||||
int resdomno;
|
||||
|
||||
rte = (RangeTblEntry *) nth(parsetree->resultRelation - 1,
|
||||
parsetree->rtable);
|
||||
rd = heap_openr(rte->relname);
|
||||
|
||||
foreach (tl, parsetree->targetList) {
|
||||
tle = (TargetEntry *)lfirst(tl);
|
||||
foreach(tl, parsetree->targetList)
|
||||
{
|
||||
tle = (TargetEntry *) lfirst(tl);
|
||||
resdomno = attnameAttNum(rd, tle->resdom->resname);
|
||||
tle->resdom->resno = resdomno;
|
||||
}
|
||||
@ -713,19 +720,19 @@ RewritePreprocessQuery(Query *parsetree)
|
||||
static Query *
|
||||
RewritePostprocessNonSelect(Query *parsetree)
|
||||
{
|
||||
List *rt;
|
||||
int rt_index = 0;
|
||||
Query *newtree = copyObject(parsetree);
|
||||
|
||||
List *rt;
|
||||
int rt_index = 0;
|
||||
Query *newtree = copyObject(parsetree);
|
||||
|
||||
foreach(rt, parsetree->rtable)
|
||||
{
|
||||
RangeTblEntry *rt_entry = lfirst(rt);
|
||||
RangeTblEntry *rt_entry = lfirst(rt);
|
||||
Relation rt_entry_relation = NULL;
|
||||
RuleLock *rt_entry_locks = NULL;
|
||||
List *locks = NIL;
|
||||
List *instead_locks = NIL;
|
||||
List *lock;
|
||||
RewriteRule *rule;
|
||||
RuleLock *rt_entry_locks = NULL;
|
||||
List *locks = NIL;
|
||||
List *instead_locks = NIL;
|
||||
List *lock;
|
||||
RewriteRule *rule;
|
||||
|
||||
rt_index++;
|
||||
rt_entry_relation = heap_openr(rt_entry->relname);
|
||||
@ -733,7 +740,8 @@ RewritePostprocessNonSelect(Query *parsetree)
|
||||
|
||||
if (rt_entry_locks)
|
||||
{
|
||||
int origcmdtype = newtree->commandType;
|
||||
int origcmdtype = newtree->commandType;
|
||||
|
||||
newtree->commandType = CMD_SELECT;
|
||||
locks =
|
||||
matchLocks(CMD_SELECT, rt_entry_locks, rt_index, newtree);
|
||||
@ -741,28 +749,29 @@ RewritePostprocessNonSelect(Query *parsetree)
|
||||
}
|
||||
if (locks != NIL)
|
||||
{
|
||||
foreach (lock, locks) {
|
||||
rule = (RewriteRule *)lfirst(lock);
|
||||
if (rule->isInstead) {
|
||||
foreach(lock, locks)
|
||||
{
|
||||
rule = (RewriteRule *) lfirst(lock);
|
||||
if (rule->isInstead)
|
||||
instead_locks = nconc(instead_locks, lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (instead_locks != NIL)
|
||||
{
|
||||
foreach (lock, instead_locks) {
|
||||
int relation_level;
|
||||
int modified = 0;
|
||||
foreach(lock, instead_locks)
|
||||
{
|
||||
int relation_level;
|
||||
int modified = 0;
|
||||
|
||||
rule = (RewriteRule *)lfirst(lock);
|
||||
rule = (RewriteRule *) lfirst(lock);
|
||||
relation_level = (rule->attrno == -1);
|
||||
|
||||
ApplyRetrieveRule(newtree,
|
||||
rule,
|
||||
rt_index,
|
||||
relation_level,
|
||||
rt_entry_relation,
|
||||
&modified);
|
||||
rule,
|
||||
rt_index,
|
||||
relation_level,
|
||||
rt_entry_relation,
|
||||
&modified);
|
||||
}
|
||||
}
|
||||
|
||||
@ -813,6 +822,7 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
|
||||
{
|
||||
List *locks =
|
||||
matchLocks(event, rt_entry_locks, result_relation, parsetree);
|
||||
|
||||
product_queries =
|
||||
fireRules(parsetree,
|
||||
result_relation,
|
||||
@ -829,16 +839,18 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
|
||||
* So we care for them here.
|
||||
* ----------
|
||||
*/
|
||||
if (product_queries != NIL) {
|
||||
List *pq;
|
||||
Query *tmp;
|
||||
List *new_products = NIL;
|
||||
|
||||
foreach (pq, product_queries) {
|
||||
tmp = (Query *)lfirst(pq);
|
||||
if (product_queries != NIL)
|
||||
{
|
||||
List *pq;
|
||||
Query *tmp;
|
||||
List *new_products = NIL;
|
||||
|
||||
foreach(pq, product_queries)
|
||||
{
|
||||
tmp = (Query *) lfirst(pq);
|
||||
tmp = RewritePostprocessNonSelect(tmp);
|
||||
new_products = lappend(new_products, tmp);
|
||||
}
|
||||
}
|
||||
product_queries = new_products;
|
||||
}
|
||||
|
||||
@ -937,7 +949,7 @@ QueryRewriteSubLink(Node *node)
|
||||
* SubLink we don't process it as part of this loop.
|
||||
*/
|
||||
QueryRewriteSubLink((Node *) query->qual);
|
||||
|
||||
|
||||
QueryRewriteSubLink((Node *) query->havingQual);
|
||||
|
||||
ret = QueryRewriteOne(query);
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.16 1998/09/01 03:24:56 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.17 1998/09/01 04:31:35 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -28,8 +28,7 @@
|
||||
#include "nodes/plannodes.h"
|
||||
#include "optimizer/clauses.h"
|
||||
|
||||
static void
|
||||
ResolveNew(RewriteInfo *info, List *targetlist,
|
||||
static void ResolveNew(RewriteInfo *info, List *targetlist,
|
||||
Node **node, int sublevels_up);
|
||||
|
||||
|
||||
@ -55,14 +54,18 @@ OffsetVarNodes(Node *node, int offset)
|
||||
OffsetVarNodes(agg->target, offset);
|
||||
}
|
||||
break;
|
||||
/* This has to be done to make queries using groupclauses work on views */
|
||||
case T_GroupClause:
|
||||
{
|
||||
GroupClause *group = (GroupClause *) node;
|
||||
|
||||
OffsetVarNodes((Node *)(group->entry), offset);
|
||||
|
||||
/*
|
||||
* This has to be done to make queries using groupclauses work
|
||||
* on views
|
||||
*/
|
||||
case T_GroupClause:
|
||||
{
|
||||
GroupClause *group = (GroupClause *) node;
|
||||
|
||||
OffsetVarNodes((Node *) (group->entry), offset);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case T_Expr:
|
||||
{
|
||||
Expr *expr = (Expr *) node;
|
||||
@ -90,16 +93,20 @@ OffsetVarNodes(Node *node, int offset)
|
||||
{
|
||||
SubLink *sublink = (SubLink *) node;
|
||||
|
||||
/* We also have to adapt the variables used in sublink->lefthand
|
||||
* and sublink->oper */
|
||||
OffsetVarNodes((Node *)(sublink->lefthand), offset);
|
||||
/*
|
||||
* We also have to adapt the variables used in
|
||||
* sublink->lefthand and sublink->oper
|
||||
*/
|
||||
OffsetVarNodes((Node *) (sublink->lefthand), offset);
|
||||
|
||||
/* Make sure the first argument of sublink->oper points to the
|
||||
* same var as sublink->lefthand does otherwise we will
|
||||
* run into troubles using aggregates (aggno will not be
|
||||
* set correctly) */
|
||||
lfirst(((Expr *) lfirst(sublink->oper))->args) =
|
||||
lfirst(sublink->lefthand);
|
||||
/*
|
||||
* Make sure the first argument of sublink->oper points to
|
||||
* the same var as sublink->lefthand does otherwise we
|
||||
* will run into troubles using aggregates (aggno will not
|
||||
* be set correctly)
|
||||
*/
|
||||
lfirst(((Expr *) lfirst(sublink->oper))->args) =
|
||||
lfirst(sublink->lefthand);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -129,15 +136,19 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
|
||||
ChangeVarNodes(agg->target, old_varno, new_varno, sublevels_up);
|
||||
}
|
||||
break;
|
||||
/* This has to be done to make queries using groupclauses work on views */
|
||||
case T_GroupClause:
|
||||
{
|
||||
GroupClause *group = (GroupClause *) node;
|
||||
|
||||
ChangeVarNodes((Node *)(group->entry),old_varno, new_varno,
|
||||
sublevels_up);
|
||||
|
||||
/*
|
||||
* This has to be done to make queries using groupclauses work
|
||||
* on views
|
||||
*/
|
||||
case T_GroupClause:
|
||||
{
|
||||
GroupClause *group = (GroupClause *) node;
|
||||
|
||||
ChangeVarNodes((Node *) (group->entry), old_varno, new_varno,
|
||||
sublevels_up);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case T_Expr:
|
||||
{
|
||||
@ -156,8 +167,9 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
|
||||
var->varno = new_varno;
|
||||
var->varnoold = new_varno;
|
||||
}
|
||||
if (var->varlevelsup > 0) OffsetVarNodes((Node *)var,3);
|
||||
|
||||
if (var->varlevelsup > 0)
|
||||
OffsetVarNodes((Node *) var, 3);
|
||||
|
||||
}
|
||||
break;
|
||||
case T_List:
|
||||
@ -176,17 +188,24 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
|
||||
ChangeVarNodes((Node *) query->qual, old_varno, new_varno,
|
||||
sublevels_up + 1);
|
||||
|
||||
/* We also have to adapt the variables used in sublink->lefthand
|
||||
* and sublink->oper */
|
||||
/*
|
||||
* We also have to adapt the variables used in
|
||||
* sublink->lefthand and sublink->oper
|
||||
*/
|
||||
ChangeVarNodes((Node *) (sublink->lefthand), old_varno, new_varno,
|
||||
sublevels_up);
|
||||
|
||||
/* Make sure the first argument of sublink->oper points to the
|
||||
* same var as sublink->lefthand does otherwise we will
|
||||
* run into troubles using aggregates (aggno will not be
|
||||
* set correctly */
|
||||
/* lfirst(((Expr *) lfirst(sublink->oper))->args) =
|
||||
lfirst(sublink->lefthand); */
|
||||
|
||||
/*
|
||||
* Make sure the first argument of sublink->oper points to
|
||||
* the same var as sublink->lefthand does otherwise we
|
||||
* will run into troubles using aggregates (aggno will not
|
||||
* be set correctly
|
||||
*/
|
||||
|
||||
/*
|
||||
* lfirst(((Expr *) lfirst(sublink->oper))->args) =
|
||||
* lfirst(sublink->lefthand);
|
||||
*/
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -218,7 +237,8 @@ AddQual(Query *parsetree, Node *qual)
|
||||
void
|
||||
AddHavingQual(Query *parsetree, Node *havingQual)
|
||||
{
|
||||
Node *copy, *old;
|
||||
Node *copy,
|
||||
*old;
|
||||
|
||||
if (havingQual == NULL)
|
||||
return;
|
||||
@ -553,18 +573,22 @@ nodeHandleViewRule(Node **nodePtr,
|
||||
Aggreg *agg = (Aggreg *) node;
|
||||
|
||||
nodeHandleViewRule(&(agg->target), rtable, targetlist,
|
||||
rt_index, modified, sublevels_up);
|
||||
rt_index, modified, sublevels_up);
|
||||
}
|
||||
break;
|
||||
/* This has to be done to make queries using groupclauses work on views */
|
||||
case T_GroupClause:
|
||||
{
|
||||
GroupClause *group = (GroupClause *) node;
|
||||
|
||||
nodeHandleViewRule((Node **) (&(group->entry)), rtable, targetlist,
|
||||
rt_index, modified, sublevels_up);
|
||||
|
||||
/*
|
||||
* This has to be done to make queries using groupclauses work
|
||||
* on views
|
||||
*/
|
||||
case T_GroupClause:
|
||||
{
|
||||
GroupClause *group = (GroupClause *) node;
|
||||
|
||||
nodeHandleViewRule((Node **) (&(group->entry)), rtable, targetlist,
|
||||
rt_index, modified, sublevels_up);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case T_Expr:
|
||||
{
|
||||
Expr *expr = (Expr *) node;
|
||||
@ -580,40 +604,39 @@ nodeHandleViewRule(Node **nodePtr,
|
||||
int this_varno = var->varno;
|
||||
int this_varlevelsup = var->varlevelsup;
|
||||
Node *n;
|
||||
|
||||
|
||||
if (this_varno == rt_index &&
|
||||
this_varlevelsup == sublevels_up)
|
||||
{
|
||||
n = FindMatchingTLEntry(targetlist,
|
||||
get_attname(getrelid(this_varno,
|
||||
rtable),
|
||||
var->varattno));
|
||||
if (n == NULL)
|
||||
{
|
||||
*nodePtr = make_null(((Var *) node)->vartype);
|
||||
}
|
||||
|
||||
else
|
||||
/* This is a hack: The varlevelsup of the orignal
|
||||
* variable and the new one should be the same.
|
||||
* Normally we adapt the node by changing a pointer
|
||||
* to point to a var contained in 'targetlist'.
|
||||
* In the targetlist all varlevelsups are 0
|
||||
* so if we want to change it to the original value
|
||||
* we have to copy the node before! (Maybe this will
|
||||
* cause troubles with some sophisticated queries on
|
||||
* views?) */
|
||||
{
|
||||
if(this_varlevelsup>0){
|
||||
*nodePtr = copyObject(n);
|
||||
this_varlevelsup == sublevels_up)
|
||||
{
|
||||
n = FindMatchingTLEntry(targetlist,
|
||||
get_attname(getrelid(this_varno,
|
||||
rtable),
|
||||
var->varattno));
|
||||
if (n == NULL)
|
||||
*nodePtr = make_null(((Var *) node)->vartype);
|
||||
|
||||
else
|
||||
|
||||
/*
|
||||
* This is a hack: The varlevelsup of the orignal
|
||||
* variable and the new one should be the same.
|
||||
* Normally we adapt the node by changing a
|
||||
* pointer to point to a var contained in
|
||||
* 'targetlist'. In the targetlist all
|
||||
* varlevelsups are 0 so if we want to change it
|
||||
* to the original value we have to copy the node
|
||||
* before! (Maybe this will cause troubles with
|
||||
* some sophisticated queries on views?)
|
||||
*/
|
||||
{
|
||||
if (this_varlevelsup > 0)
|
||||
*nodePtr = copyObject(n);
|
||||
else
|
||||
*nodePtr = n;
|
||||
((Var *) *nodePtr)->varlevelsup = this_varlevelsup;
|
||||
}
|
||||
else {
|
||||
*nodePtr = n;
|
||||
}
|
||||
((Var *)*nodePtr)->varlevelsup = this_varlevelsup;
|
||||
}
|
||||
*modified = TRUE;
|
||||
}
|
||||
*modified = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_List:
|
||||
@ -634,20 +657,24 @@ nodeHandleViewRule(Node **nodePtr,
|
||||
Query *query = (Query *) sublink->subselect;
|
||||
|
||||
nodeHandleViewRule((Node **) &(query->qual), rtable, targetlist,
|
||||
rt_index, modified, sublevels_up + 1);
|
||||
|
||||
/* We also have to adapt the variables used in sublink->lefthand
|
||||
* and sublink->oper */
|
||||
nodeHandleViewRule((Node **) &(sublink->lefthand), rtable,
|
||||
targetlist, rt_index, modified, sublevels_up);
|
||||
|
||||
/* Make sure the first argument of sublink->oper points to the
|
||||
* same var as sublink->lefthand does otherwise we will
|
||||
* run into troubles using aggregates (aggno will not be
|
||||
* set correctly */
|
||||
rt_index, modified, sublevels_up + 1);
|
||||
|
||||
/*
|
||||
* We also have to adapt the variables used in
|
||||
* sublink->lefthand and sublink->oper
|
||||
*/
|
||||
nodeHandleViewRule((Node **) &(sublink->lefthand), rtable,
|
||||
targetlist, rt_index, modified, sublevels_up);
|
||||
|
||||
/*
|
||||
* Make sure the first argument of sublink->oper points to
|
||||
* the same var as sublink->lefthand does otherwise we
|
||||
* will run into troubles using aggregates (aggno will not
|
||||
* be set correctly
|
||||
*/
|
||||
pfree(lfirst(((Expr *) lfirst(sublink->oper))->args));
|
||||
lfirst(((Expr *) lfirst(sublink->oper))->args) =
|
||||
lfirst(sublink->lefthand);
|
||||
lfirst(((Expr *) lfirst(sublink->oper))->args) =
|
||||
lfirst(sublink->lefthand);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -667,10 +694,13 @@ HandleViewRule(Query *parsetree,
|
||||
modified, 0);
|
||||
nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
|
||||
rt_index, modified, 0);
|
||||
/* The variables in the havingQual and groupClause also have to be adapted */
|
||||
|
||||
/*
|
||||
* The variables in the havingQual and groupClause also have to be
|
||||
* adapted
|
||||
*/
|
||||
nodeHandleViewRule(&parsetree->havingQual, rtable, targetlist, rt_index,
|
||||
modified, 0);
|
||||
nodeHandleViewRule((Node **) (&(parsetree->groupClause)), rtable, targetlist, rt_index,
|
||||
modified, 0);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.17 1998/09/01 03:24:57 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.18 1998/09/01 04:31:36 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -36,15 +36,15 @@ RewriteGetRuleEventRel(char *rulename)
|
||||
Oid eventrel;
|
||||
|
||||
htup = SearchSysCacheTuple(REWRITENAME,
|
||||
PointerGetDatum(rulename),
|
||||
0, 0, 0);
|
||||
PointerGetDatum(rulename),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(htup))
|
||||
elog(ERROR, "RewriteGetRuleEventRel: rule \"%s\" not found",
|
||||
rulename);
|
||||
eventrel = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
|
||||
htup = SearchSysCacheTuple(RELOID,
|
||||
PointerGetDatum(eventrel),
|
||||
0, 0, 0);
|
||||
PointerGetDatum(eventrel),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(htup))
|
||||
elog(ERROR, "RewriteGetRuleEventRel: class %d not found",
|
||||
eventrel);
|
||||
@ -87,6 +87,7 @@ RemoveRewriteRule(char *ruleName)
|
||||
tuple = SearchSysCacheTupleCopy(REWRITENAME,
|
||||
PointerGetDatum(ruleName),
|
||||
0, 0, 0);
|
||||
|
||||
/*
|
||||
* complain if no rule with such name existed
|
||||
*/
|
||||
@ -101,10 +102,10 @@ RemoveRewriteRule(char *ruleName)
|
||||
* relation's OID
|
||||
*/
|
||||
ruleId = tuple->t_oid;
|
||||
eventRelationOidDatum = heap_getattr(tuple,
|
||||
Anum_pg_rewrite_ev_class,
|
||||
RelationGetDescr(RewriteRelation),
|
||||
&isNull);
|
||||
eventRelationOidDatum = heap_getattr(tuple,
|
||||
Anum_pg_rewrite_ev_class,
|
||||
RelationGetDescr(RewriteRelation),
|
||||
&isNull);
|
||||
if (isNull)
|
||||
{
|
||||
/* XXX strange!!! */
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.27 1998/09/01 03:24:59 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.28 1998/09/01 04:31:37 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -99,8 +99,9 @@ IsDefinedRewriteRule(char *ruleName)
|
||||
RewriteRelation = heap_openr(RewriteRelationName);
|
||||
|
||||
tuple = SearchSysCacheTuple(REWRITENAME,
|
||||
PointerGetDatum(ruleName),
|
||||
0, 0, 0);
|
||||
PointerGetDatum(ruleName),
|
||||
0, 0, 0);
|
||||
|
||||
/*
|
||||
* return whether or not the rewrite rule existed
|
||||
*/
|
||||
@ -121,12 +122,12 @@ setRelhasrulesInRelation(Oid relationId, bool relhasrules)
|
||||
* lock to it.
|
||||
*/
|
||||
tuple = SearchSysCacheTupleCopy(RELOID,
|
||||
ObjectIdGetDatum(relationId),
|
||||
0, 0, 0);
|
||||
ObjectIdGetDatum(relationId),
|
||||
0, 0, 0);
|
||||
Assert(HeapTupleIsValid(tuple));
|
||||
|
||||
relationRelation = heap_openr(RelationRelationName);
|
||||
((Form_pg_class)GETSTRUCT(tuple))->relhasrules = relhasrules;
|
||||
((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relhasrules;
|
||||
heap_replace(relationRelation, &tuple->t_ctid, tuple);
|
||||
|
||||
/* keep the catalog indices up to date */
|
||||
|
Reference in New Issue
Block a user