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

Function ATPrepSetNotNull

src/backend/commands/tablecmds.c:9144–9207  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

9142 */
9143
9144static void
9145ATPrepSetNotNull(List **wqueue, Relation rel,
9146 AlterTableCmd *cmd, bool recurse, bool recursing,
9147 LOCKMODE lockmode, AlterTableUtilityContext *context)
9148{
9149 /*
9150 * If we're already recursing, there's nothing to do; the topmost
9151 * invocation of ATSimpleRecursion already visited all children.
9152 */
9153 if (recursing)
9154 return;
9155
9156 /*
9157 * If the target column is already marked NOT NULL, we can skip recursing
9158 * to children, because their columns should already be marked NOT NULL as
9159 * well. But there's no point in checking here unless the relation has
9160 * some children; else we can just wait till execution to check. (If it
9161 * does have children, however, this can save taking per-child locks
9162 * unnecessarily. This greatly improves concurrency in some parallel
9163 * restore scenarios.)
9164 *
9165 * Unfortunately, we can only apply this optimization to partitioned
9166 * tables, because traditional inheritance doesn't enforce that child
9167 * columns be NOT NULL when their parent is. (That's a bug that should
9168 * get fixed someday.)
9169 */
9170 if (rel->rd_rel->relhassubclass &&
9171 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
9172 {
9173 HeapTuple tuple;
9174 bool attnotnull;
9175
9176 tuple = SearchSysCacheAttName(RelationGetRelid(rel), cmd->name);
9177
9178 /* Might as well throw the error now, if name is bad */
9179 if (!HeapTupleIsValid(tuple))
9180 ereport(ERROR,
9181 (errcode(ERRCODE_UNDEFINED_COLUMN),
9182 errmsg("column \"%s\" of relation \"%s\" does not exist",
9183 cmd->name, RelationGetRelationName(rel))));
9184
9185 attnotnull = ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull;
9186 ReleaseSysCache(tuple);
9187 if (attnotnull)
9188 return;
9189 }
9190
9191 /*
9192 * If we have ALTER TABLE ONLY ... SET NOT NULL on a partitioned table,
9193 * apply ALTER TABLE ... CHECK NOT NULL to every child. Otherwise, use
9194 * normal recursion logic.
9195 */
9196 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
9197 !recurse)
9198 {
9199 AlterTableCmd *newcmd = makeNode(AlterTableCmd);
9200
9201 newcmd->subtype = AT_CheckNotNull;

Callers 2

ATPrepCmdFunction · 0.85
ATParseTransformCmdFunction · 0.85

Calls 6

SearchSysCacheAttNameFunction · 0.85
ReleaseSysCacheFunction · 0.85
ATSimpleRecursionFunction · 0.85
errcodeFunction · 0.50
errmsgFunction · 0.50
pstrdupFunction · 0.50

Tested by

no test coverage detected