aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/cluster.c12
-rw-r--r--src/backend/commands/functioncmds.c2
-rw-r--r--src/backend/commands/indexcmds.c4
-rw-r--r--src/backend/commands/tablecmds.c51
-rw-r--r--src/backend/commands/typecmds.c2
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