* Recursively mark all relations used by a view as FOR [KEY] UPDATE/SHARE. * * This may generate an invalid query, eg if some sub-query uses an * aggregate. We leave it to the planner to detect that. * * NB: this must agree with the parser's transformLockingClause() routine. * However, unlike the parser we have to be careful not to mark a view's * OLD and NEW rels for updating. The best w
| 1957 | * to scan the jointree to determine which rels are used. |
| 1958 | */ |
| 1959 | static void |
| 1960 | markQueryForLocking(Query *qry, Node *jtnode, |
| 1961 | LockClauseStrength strength, LockWaitPolicy waitPolicy, |
| 1962 | bool pushedDown) |
| 1963 | { |
| 1964 | if (jtnode == NULL) |
| 1965 | return; |
| 1966 | if (IsA(jtnode, RangeTblRef)) |
| 1967 | { |
| 1968 | int rti = ((RangeTblRef *) jtnode)->rtindex; |
| 1969 | RangeTblEntry *rte = rt_fetch(rti, qry->rtable); |
| 1970 | |
| 1971 | if (rte->rtekind == RTE_RELATION) |
| 1972 | { |
| 1973 | applyLockingClause(qry, rti, strength, waitPolicy, pushedDown); |
| 1974 | rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; |
| 1975 | } |
| 1976 | else if (rte->rtekind == RTE_SUBQUERY) |
| 1977 | { |
| 1978 | applyLockingClause(qry, rti, strength, waitPolicy, pushedDown); |
| 1979 | /* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */ |
| 1980 | markQueryForLocking(rte->subquery, (Node *) rte->subquery->jointree, |
| 1981 | strength, waitPolicy, true); |
| 1982 | } |
| 1983 | /* other RTE types are unaffected by FOR UPDATE */ |
| 1984 | } |
| 1985 | else if (IsA(jtnode, FromExpr)) |
| 1986 | { |
| 1987 | FromExpr *f = (FromExpr *) jtnode; |
| 1988 | ListCell *l; |
| 1989 | |
| 1990 | foreach(l, f->fromlist) |
| 1991 | markQueryForLocking(qry, lfirst(l), strength, waitPolicy, pushedDown); |
| 1992 | } |
| 1993 | else if (IsA(jtnode, JoinExpr)) |
| 1994 | { |
| 1995 | JoinExpr *j = (JoinExpr *) jtnode; |
| 1996 | |
| 1997 | markQueryForLocking(qry, j->larg, strength, waitPolicy, pushedDown); |
| 1998 | markQueryForLocking(qry, j->rarg, strength, waitPolicy, pushedDown); |
| 1999 | } |
| 2000 | else |
| 2001 | elog(ERROR, "unrecognized node type: %d", |
| 2002 | (int) nodeTag(jtnode)); |
| 2003 | } |
| 2004 | |
| 2005 | |
| 2006 | /* |
no test coverage detected