wieck@debis.com (Jan Wieck) writes:
> I think it's correct to MOVE the inFromCl from the relation
> rewritten to the join relations coming with the view's rule.
> Thus clear it on the RTE rewritten and on the first two of
> the rules (which are allways NEW and OLD for all rules). Then
> set all other RTE's which come from the view to the former
> inFromCl state of the rewritten RTE.
OK, I will do that. My first-cut code (attached, please look it over)
passes regress test without it, but we know how much that's worth ;-).
Actually I think moving inJoinSet is now the important thing...
regards, tom lane
All mention of inFromCl/inJoinSet removed from ApplyRetrieveRule;
fireRIRrules loop looks like:
rt_index = 0; while (rt_index < length(parsetree->rtable)) { ++rt_index;
rte = nth(rt_index - 1, parsetree->rtable);
/* * If the table is not one named in the original FROM clause * then it must be referenced in the
query,or we ignore it. * This prevents infinite expansion loop due to new rtable * entries inserted by
expansionof a rule. */ if (! rte->inFromCl && rt_index != parsetree->resultRelation && !
rangeTableEntry_used((Node*) parsetree, rt_index, 0)) { /* Make sure the planner ignores it too... */
rte->inJoinSet = false; continue; }
rel = heap_openr(rte->relname, AccessShareLock); rules = rel->rd_rules; if (rules == NULL) {
heap_close(rel, AccessShareLock); continue; }
locks = NIL;
/* * Collect the RIR rules that we must apply */ for (i = 0; i < rules->numLocks; i++)
{ rule = rules->rules[i]; if (rule->event != CMD_SELECT) continue;
if (rule->attrno > 0) { /* per-attr rule; do we need it? */ if (!
attribute_used((Node*) parsetree, rt_index,
rule->attrno,0)) continue; } else { /* Rel-wide ON SELECT
DOINSTEAD means this is a view. * Remove the view from the planner's join target set, *
orwe'll get no rows out because view itself is empty! */ if (rule->isInstead)
rte->inJoinSet = false; }
locks = lappend(locks, rule); }
/* * Check permissions */ checkLockPerms(locks, parsetree, rt_index);
/* * Now apply them */ foreach(l, locks) { rule = lfirst(l);
RIRonly.event = rule->event; RIRonly.attrno = rule->attrno; RIRonly.qual = rule->qual;
RIRonly.actions = rule->actions;
parsetree = ApplyRetrieveRule(parsetree, &RIRonly,
rt_index, RIRonly.attrno == -1,
rel, &modified); }
heap_close(rel, AccessShareLock); }