* AcquireRewriteLocks - * Acquire suitable locks on all the relations mentioned in the Query. * These locks will ensure that the relation schemas don't change under us * while we are rewriting, planning, and executing the query. * * Caution: this may modify the querytree, therefore caller should usually * have done a copyObject() to make a writable copy of the querytree in the * curre
| 139 | * construction of a nested join was O(N^2) in the nesting depth.) |
| 140 | */ |
| 141 | void |
| 142 | AcquireRewriteLocks(Query *parsetree, |
| 143 | bool forExecute, |
| 144 | bool forUpdatePushedDown) |
| 145 | { |
| 146 | ListCell *l; |
| 147 | int rt_index; |
| 148 | acquireLocksOnSubLinks_context context; |
| 149 | |
| 150 | context.for_execute = forExecute; |
| 151 | |
| 152 | /* |
| 153 | * First, process RTEs of the current query level. |
| 154 | */ |
| 155 | rt_index = 0; |
| 156 | foreach(l, parsetree->rtable) |
| 157 | { |
| 158 | RangeTblEntry *rte = (RangeTblEntry *) lfirst(l); |
| 159 | Relation rel; |
| 160 | LOCKMODE lockmode; |
| 161 | bool needLockUpgrade; |
| 162 | List *newaliasvars; |
| 163 | Index curinputvarno; |
| 164 | RangeTblEntry *curinputrte; |
| 165 | ListCell *ll; |
| 166 | |
| 167 | ++rt_index; |
| 168 | switch (rte->rtekind) |
| 169 | { |
| 170 | case RTE_RELATION: |
| 171 | |
| 172 | /* |
| 173 | * Grab the appropriate lock type for the relation, and do not |
| 174 | * release it until end of transaction. This protects the |
| 175 | * rewriter, planner, and executor against schema changes |
| 176 | * mid-query. |
| 177 | * |
| 178 | * If forExecute is false, ignore rellockmode and just use |
| 179 | * AccessShareLock. |
| 180 | * |
| 181 | * CDB: The proper lock mode depends on whether the relation is |
| 182 | * local or distributed, which is discovered by heap_open(). |
| 183 | * To handle this we make use of CdbOpenRelation(). |
| 184 | * |
| 185 | * For update should hold ExclusiveLock, see the discussion on |
| 186 | * https://groups.google.com/a/greenplum.org/d/msg/gpdb-dev/p-6_dNjnRMQ/OzTnb586AwAJ |
| 187 | * |
| 188 | * Update|DELETE may have to upgrade the locks to avoid global |
| 189 | * deadlock and CdbOpenRelation will do more check for AO table |
| 190 | * and GDD's status. |
| 191 | */ |
| 192 | needLockUpgrade = false; |
| 193 | if (!forExecute) |
| 194 | lockmode = AccessShareLock; |
| 195 | else if (rt_index == parsetree->resultRelation) |
| 196 | { |
| 197 | lockmode = RowExclusiveLock; |
| 198 | needLockUpgrade = (parsetree->commandType == CMD_UPDATE || |
no test coverage detected