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

Function ExecCheckXactReadOnly

src/backend/executor/execMain.c:1657–1743  ·  view source on GitHub ↗

* Check that the query does not imply any writes to non-temp tables; * unless we're in parallel mode, in which case don't even allow writes * to temp tables. * * This function is used to check if the current statement will perform any writes. * It is used to enforce: * (1) read-only mode (both fts and transaction isolation level read only) * as well as * (2) to keep track of when a

Source from the content-addressed store, hash-verified

1655 * ensures that we use two-phase commit for this transaction.
1656 */
1657static void
1658ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
1659{
1660 ListCell *l;
1661 int rti;
1662
1663 /*
1664 * CREATE TABLE AS or SELECT INTO?
1665 *
1666 * XXX should we allow this if the destination is temp? Considering that
1667 * it would still require catalog changes, probably not.
1668 */
1669 if (plannedstmt->intoClause != NULL)
1670 {
1671 if ((plannedstmt->intoClause->rel && plannedstmt->intoClause->rel->relpersistence == RELPERSISTENCE_TEMP)
1672 || (plannedstmt->intoClause->rel == NULL && plannedstmt->intoClause->ivm))
1673 ExecutorMarkTransactionDoesWrites();
1674 else
1675 PreventCommandIfReadOnly(CreateCommandName((Node *) plannedstmt));
1676 }
1677
1678 /*
1679 * Refresh matview will write xlog.
1680 */
1681 if (plannedstmt->refreshClause != NULL)
1682 {
1683 PreventCommandIfReadOnly(CreateCommandName((Node *) plannedstmt));
1684 }
1685
1686 rti = 0;
1687 /*
1688 * Fail if write permissions are requested in parallel mode for table
1689 * (temp or non-temp), otherwise fail for any non-temp table.
1690 */
1691 foreach(l, plannedstmt->rtable)
1692 {
1693 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
1694
1695 rti++;
1696
1697 if (rte->rtekind != RTE_RELATION)
1698 continue;
1699
1700 if ((rte->requiredPerms & (~ACL_SELECT)) == 0)
1701 continue;
1702
1703 /*
1704 * External and foreign tables don't need two phase commit which is for
1705 * local mpp tables
1706 */
1707 if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
1708 continue;
1709
1710 if (isTempNamespace(get_rel_namespace(rte->relid)))
1711 {
1712 ExecutorMarkTransactionDoesWrites();
1713 continue;
1714 }

Callers 1

standard_ExecutorStartFunction · 0.85

Calls 8

PreventCommandIfReadOnlyFunction · 0.85
CreateCommandNameFunction · 0.85
get_rel_relkindFunction · 0.85
isTempNamespaceFunction · 0.85
get_rel_namespaceFunction · 0.85
foreachFunction · 0.50

Tested by

no test coverage detected