MCPcopy Create free account
hub / github.com/apache/cloudberry / setTargetTable

Function setTargetTable

src/backend/parser/parse_clause.c:261–381  ·  view source on GitHub ↗

* setTargetTable * Add the target relation of INSERT/UPDATE/DELETE to the range table, * and make the special links to it in the ParseState. * * We also open the target relation and acquire a write lock on it. * This must be done before processing the FROM list, in case the target * is also mentioned as a source relation --- we want to be sure to grab * the write lock before any

Source from the content-addressed store, hash-verified

259 * Returns the rangetable index of the target relation.
260 */
261int
262setTargetTable(ParseState *pstate, RangeVar *relation,
263 bool inh, bool alsoSource, AclMode requiredPerms)
264{
265 ParseCallbackState pcbstate;
266 ParseNamespaceItem *nsitem;
267 bool lockUpgraded = false;
268 LOCKMODE lockmode;
269
270 /*
271 * ENRs hide tables of the same name, so we need to check for them first.
272 * In contrast, CTEs don't hide tables (for this purpose).
273 */
274 if (relation->schemaname == NULL &&
275 scanNameSpaceForENR(pstate, relation->relname))
276 ereport(ERROR,
277 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
278 errmsg("relation \"%s\" cannot be the target of a modifying statement",
279 relation->relname)));
280
281 /* Close old target; this could only happen for multi-action rules */
282 if (pstate->p_target_relation != NULL)
283 table_close(pstate->p_target_relation, NoLock);
284
285 /*
286 * Open target rel and grab suitable lock (which we will hold till end of
287 * transaction).
288 *
289 * free_parsestate() will eventually do the corresponding table_close(),
290 * but *not* release the lock.
291 *
292 * CDB: Acquire ExclusiveLock if it is a distributed relation and we are
293 * doing UPDATE or DELETE activity or `insert on conflict do update`.
294 *
295 * We should use heap_openrv instead of parserOpenTable for inserts because
296 * parserOpenTable upgrades the lock to Exclusive mode for distributed
297 * tables.
298 *
299 * Cloudberry specific behavior:
300 * Statement `insert on conflict do update` should be considered
301 * like update when deducting lockmode. See github issue:
302 * https://github.com/greenplum-db/gpdb/issues/9449
303 */
304 if (pstate->p_is_insert && !pstate->p_is_on_conflict_update)
305 {
306 setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
307 pstate->p_target_relation = heap_openrv(relation, RowExclusiveLock);
308 cancel_parser_errposition_callback(&pcbstate);
309 }
310 else
311 {
312 pstate->p_target_relation = parserOpenTable(pstate, relation, RowExclusiveLock, &lockUpgraded);
313 }
314
315 lockmode = lockUpgraded ? ExclusiveLock : RowExclusiveLock;
316
317 if (Gp_role == GP_ROLE_DISPATCH &&
318 pstate->p_is_insert &&

Callers 3

transformDeleteStmtFunction · 0.85
transformInsertStmtFunction · 0.85
transformUpdateStmtFunction · 0.85

Calls 11

scanNameSpaceForENRFunction · 0.85
table_closeFunction · 0.85
parserOpenTableFunction · 0.85
find_all_inheritorsFunction · 0.85
IsSystemRelationFunction · 0.85
addNSItemToQueryFunction · 0.85
errcodeFunction · 0.50
errmsgFunction · 0.50

Tested by

no test coverage detected