* Add an entry for a relation to the pstate's range table (p_rtable). * Then, construct and return a ParseNamespaceItem for the new RTE. * * We do not link the ParseNamespaceItem into the pstate here; it's the * caller's job to do that in the appropriate way. * * Note: formerly this checked for refname conflicts, but that's wrong. * Caller is responsible for checking for conflicts in the ap
| 1431 | * Caller is responsible for checking for conflicts in the appropriate scope. |
| 1432 | */ |
| 1433 | ParseNamespaceItem * |
| 1434 | addRangeTableEntry(ParseState *pstate, |
| 1435 | RangeVar *relation, |
| 1436 | Alias *alias, |
| 1437 | bool inh, |
| 1438 | bool inFromCl) |
| 1439 | { |
| 1440 | RangeTblEntry *rte = makeNode(RangeTblEntry); |
| 1441 | char *refname = alias ? alias->aliasname : relation->relname; |
| 1442 | LOCKMODE lockmode = AccessShareLock; |
| 1443 | LockingClause *locking; |
| 1444 | Relation rel; |
| 1445 | ParseNamespaceItem *nsitem; |
| 1446 | |
| 1447 | Assert(pstate != NULL); |
| 1448 | |
| 1449 | rte->alias = alias; |
| 1450 | rte->rtekind = RTE_RELATION; |
| 1451 | |
| 1452 | /* |
| 1453 | * Identify the type of lock we'll need on this relation. It's not the |
| 1454 | * query's target table (that case is handled elsewhere), so we need |
| 1455 | * either RowShareLock if it's locked by FOR UPDATE/SHARE, or plain |
| 1456 | * AccessShareLock otherwise. |
| 1457 | */ |
| 1458 | /* |
| 1459 | * Cloudberry specific behavior: |
| 1460 | * The implementation of select statement with locking clause |
| 1461 | * (for update | no key update | share | key share) in postgres |
| 1462 | * is to hold RowShareLock on tables during parsing stage, and |
| 1463 | * generate a LockRows plan node for executor to lock the tuples. |
| 1464 | * It is not easy to lock tuples in Apache Cloudberry, since |
| 1465 | * tuples may be fetched through motion nodes. |
| 1466 | * |
| 1467 | * But when Global Deadlock Detector is enabled, and the select |
| 1468 | * statement with locking clause contains only one table, we are |
| 1469 | * sure that there are no motions. For such simple cases, we could |
| 1470 | * make the behavior just the same as Postgres. |
| 1471 | */ |
| 1472 | locking = getLockedRefname(pstate, refname); |
| 1473 | if (locking) |
| 1474 | { |
| 1475 | Oid relid; |
| 1476 | |
| 1477 | relid = RangeVarGetRelid(relation, lockmode, false); |
| 1478 | |
| 1479 | rel = try_table_open(relid, NoLock, true); |
| 1480 | if (!rel) |
| 1481 | elog(ERROR, "open relation(%u) fail", relid); |
| 1482 | |
| 1483 | if (rel->rd_rel->relkind != RELKIND_RELATION || |
| 1484 | GpPolicyIsReplicated(rel->rd_cdbpolicy) || |
| 1485 | RelationIsAppendOptimized(rel)) |
| 1486 | pstate->p_canOptSelectLockingClause = false; |
| 1487 | |
| 1488 | if (rel->rd_rel->relkind == RELKIND_MATVIEW || |
| 1489 | rel->rd_rel->relkind == RELKIND_DIRECTORY_TABLE) |
| 1490 | ereport(ERROR, |
no test coverage detected