diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/cluster.c | 12 | ||||
-rw-r--r-- | src/backend/commands/functioncmds.c | 2 | ||||
-rw-r--r-- | src/backend/commands/indexcmds.c | 4 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 51 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 2 |
5 files changed, 53 insertions, 18 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 57f3917fdc4..639b6992d53 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -453,7 +453,7 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMOD * seqscan pass over the table to copy the missing rows, but that seems * expensive and tedious. */ - if (!heap_attisnull(OldIndex->rd_indextuple, Anum_pg_index_indpred)) + if (!heap_attisnull(OldIndex->rd_indextuple, Anum_pg_index_indpred, NULL)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot cluster on partial index \"%s\"", @@ -1669,6 +1669,16 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, } relation_close(newrel, NoLock); } + + /* if it's not a catalog table, clear any missing attribute settings */ + if (!is_system_catalog) + { + Relation newrel; + + newrel = heap_open(OIDOldHeap, NoLock); + RelationClearMissing(newrel); + relation_close(newrel, NoLock); + } } diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 86fa8c0dd74..c46493dd88b 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -2252,7 +2252,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); - if (!heap_attisnull(tp, Anum_pg_proc_proconfig)) + if (!heap_attisnull(tp, Anum_pg_proc_proconfig, NULL)) callcontext->atomic = true; ReleaseSysCache(tp); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 0a2ab500238..01859707940 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -215,8 +215,8 @@ CheckIndexCompatible(Oid oldId, * We don't assess expressions or predicates; assume incompatibility. * Also, if the index is invalid for any reason, treat it as incompatible. */ - if (!(heap_attisnull(tuple, Anum_pg_index_indpred) && - heap_attisnull(tuple, Anum_pg_index_indexprs) && + if (!(heap_attisnull(tuple, Anum_pg_index_indpred, NULL) && + heap_attisnull(tuple, Anum_pg_index_indexprs, NULL) && IndexIsValid(indexForm))) { ReleaseSysCache(tuple); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e74fb1f4691..83a881eff38 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -714,6 +714,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault)); rawEnt->attnum = attnum; rawEnt->raw_default = colDef->raw_default; + rawEnt->missingMode = false; rawDefaults = lappend(rawDefaults, rawEnt); attr->atthasdef = true; } @@ -4682,7 +4683,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) { int attn = lfirst_int(l); - if (heap_attisnull(tuple, attn + 1)) + if (heap_attisnull(tuple, attn + 1, newTupDesc)) { Form_pg_attribute attr = TupleDescAttr(newTupDesc, attn); @@ -4785,7 +4786,7 @@ ATGetQueueEntry(List **wqueue, Relation rel) tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo)); tab->relid = relid; tab->relkind = rel->rd_rel->relkind; - tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel)); + tab->oldDesc = CreateTupleDescCopyConstr(RelationGetDescr(rel)); tab->newrelpersistence = RELPERSISTENCE_PERMANENT; tab->chgPersistence = false; @@ -5404,6 +5405,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, attribute.attalign = tform->typalign; attribute.attnotnull = colDef->is_not_null; attribute.atthasdef = false; + attribute.atthasmissing = false; attribute.attidentity = colDef->identity; attribute.attisdropped = false; attribute.attislocal = colDef->is_local; @@ -5449,6 +5451,13 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, rawEnt->raw_default = copyObject(colDef->raw_default); /* + * Attempt to skip a complete table rewrite by storing the specified + * DEFAULT value outside of the heap. This may be disabled inside + * AddRelationNewConstraints if the optimization cannot be applied. + */ + rawEnt->missingMode = true; + + /* * This function is intended for CREATE TABLE, so it processes a * _list_ of defaults, but we just do one. */ @@ -5457,6 +5466,13 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* Make the additional catalog changes visible */ CommandCounterIncrement(); + + /* + * Did the request for a missing value work? If not we'll have to do + * a rewrite + */ + if (!rawEnt->missingMode) + tab->rewrite |= AT_REWRITE_DEFAULT_VAL; } /* @@ -5502,6 +5518,9 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, nve->typeId = typeOid; defval = (Expr *) nve; + + /* must do a rewrite for identity columns */ + tab->rewrite |= AT_REWRITE_DEFAULT_VAL; } else defval = (Expr *) build_column_default(rel, attribute.attnum); @@ -5537,16 +5556,21 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, newval->expr = expression_planner(defval); tab->newvals = lappend(tab->newvals, newval); - tab->rewrite |= AT_REWRITE_DEFAULT_VAL; } - /* - * If the new column is NOT NULL, tell Phase 3 it needs to test that. - * (Note we don't do this for an OID column. OID will be marked not - * null, but since it's filled specially, there's no need to test - * anything.) - */ - tab->new_notnull |= colDef->is_not_null; + if (DomainHasConstraints(typeOid)) + tab->rewrite |= AT_REWRITE_DEFAULT_VAL; + + if (!TupleDescAttr(rel->rd_att, attribute.attnum - 1)->atthasmissing) + { + /* + * If the new column is NOT NULL, and there is no missing value, + * tell Phase 3 it needs to test that. (Note we don't do this for + * an OID column. OID will be marked not null, but since it's + * filled specially, there's no need to test anything.) + */ + tab->new_notnull |= colDef->is_not_null; + } } /* @@ -6022,6 +6046,7 @@ ATExecColumnDefault(Relation rel, const char *colName, rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault)); rawEnt->attnum = attnum; rawEnt->raw_default = newDefault; + rawEnt->missingMode = false; /* * This function is intended for CREATE TABLE, so it processes a @@ -8109,8 +8134,8 @@ transformFkeyCheckAttrs(Relation pkrel, if (indexStruct->indnatts == numattrs && indexStruct->indisunique && IndexIsValid(indexStruct) && - heap_attisnull(indexTuple, Anum_pg_index_indpred) && - heap_attisnull(indexTuple, Anum_pg_index_indexprs)) + heap_attisnull(indexTuple, Anum_pg_index_indpred, NULL) && + heap_attisnull(indexTuple, Anum_pg_index_indexprs, NULL)) { Datum indclassDatum; bool isnull; @@ -9516,7 +9541,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true, true); - StoreAttrDefault(rel, attnum, defaultexpr, true); + StoreAttrDefault(rel, attnum, defaultexpr, true, false); } ObjectAddressSubSet(address, RelationRelationId, diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 25221965e9e..2fdcb7f3fd3 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -2397,7 +2397,7 @@ AlterDomainNotNull(List *names, bool notNull) int attnum = rtc->atts[i]; Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1); - if (heap_attisnull(tuple, attnum)) + if (heap_attisnull(tuple, attnum, tupdesc)) { /* * In principle the auxiliary information for this |