summaryrefslogtreecommitdiffstats
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/dbcommands.c6
-rw-r--r--src/backend/commands/tablecmds.c77
-rw-r--r--src/backend/commands/vacuum.c28
3 files changed, 76 insertions, 35 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 5ced6da..40fd36d 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -994,15 +994,15 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char *strategy;
strategy = defGetString(dstrategy);
- if (strcmp(strategy, "wal_log") == 0)
+ if (pg_strcasecmp(strategy, "wal_log") == 0)
dbstrategy = CREATEDB_WAL_LOG;
- else if (strcmp(strategy, "file_copy") == 0)
+ else if (pg_strcasecmp(strategy, "file_copy") == 0)
dbstrategy = CREATEDB_FILE_COPY;
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid create database strategy \"%s\"", strategy),
- errhint("Valid strategies are \"wal_log\", and \"file_copy\".")));
+ errhint("Valid strategies are \"wal_log\" and \"file_copy\".")));
}
/* If encoding or locales are defaulted, use source's setting */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 5daa560..81dd5f4 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -782,10 +782,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
}
else if (stmt->partbound)
{
- /*
- * For partitions, when no other tablespace is specified, we default
- * the tablespace to the parent partitioned table's.
- */
Assert(list_length(inheritOids) == 1);
tablespaceId = get_rel_tablespace(linitial_oid(inheritOids));
}
@@ -6745,6 +6741,9 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
TupleDesc tupdesc;
FormData_pg_attribute *aattr[] = {&attribute};
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
/* At top level, permission check was done in ATPrepCmd, else do it */
if (recursing)
ATSimplePermissions((*cmd)->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
@@ -8477,6 +8476,10 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
/* Initialize addrs on the first invocation */
Assert(!recursing || addrs != NULL);
+
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
if (!recursing)
addrs = new_object_addresses();
@@ -10939,6 +10942,9 @@ ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel,
Oid refrelid;
bool changed = false;
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
currcon = (Form_pg_constraint) GETSTRUCT(contuple);
conoid = currcon->oid;
refrelid = currcon->confrelid;
@@ -11955,6 +11961,9 @@ ATExecDropConstraint(Relation rel, const char *constrName,
bool is_no_inherit_constraint = false;
char contype;
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+
/* At top level, permission check was done in ATPrepCmd, else do it */
if (recursing)
ATSimplePermissions(AT_DropConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
@@ -12695,8 +12704,29 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
RememberConstraintForRebuilding(foundObject.objectId, tab);
break;
+ case OCLASS_PROC:
+
+ /*
+ * A new-style SQL function can depend on a column, if that
+ * column is referenced in the parsed function body. Ideally
+ * we'd automatically update the function by deparsing and
+ * reparsing it, but that's risky and might well fail anyhow.
+ * FIXME someday.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter type of a column used by a function or procedure"),
+ errdetail("%s depends on column \"%s\"",
+ getObjectDescription(&foundObject, false),
+ colName)));
+ break;
+
case OCLASS_REWRITE:
- /* XXX someday see if we can cope with revising views */
+
+ /*
+ * View/rule bodies have pretty much the same issues as
+ * function bodies. FIXME someday.
+ */
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot alter type of a column used by a view or rule"),
@@ -12712,9 +12742,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
* specified as an update target, or because the column is
* used in the trigger's WHEN condition. The first case would
* not require any extra work, but the second case would
- * require updating the WHEN expression, which will take a
- * significant amount of new code. Since we can't easily tell
- * which case applies, we punt for both. FIXME someday.
+ * require updating the WHEN expression, which has the same
+ * issues as above. Since we can't easily tell which case
+ * applies, we punt for both. FIXME someday.
*/
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -12786,7 +12816,20 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
RememberStatisticsForRebuilding(foundObject.objectId, tab);
break;
- case OCLASS_PROC:
+ case OCLASS_PUBLICATION_REL:
+
+ /*
+ * Column reference in a PUBLICATION ... FOR TABLE ... WHERE
+ * clause. Same issues as above. FIXME someday.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter type of a column used by a publication WHERE clause"),
+ errdetail("%s depends on column \"%s\"",
+ getObjectDescription(&foundObject, false),
+ colName)));
+ break;
+
case OCLASS_TYPE:
case OCLASS_CAST:
case OCLASS_COLLATION:
@@ -12816,7 +12859,6 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
case OCLASS_PARAMETER_ACL:
case OCLASS_PUBLICATION:
case OCLASS_PUBLICATION_NAMESPACE:
- case OCLASS_PUBLICATION_REL:
case OCLASS_SUBSCRIPTION:
case OCLASS_TRANSFORM:
@@ -16564,16 +16606,11 @@ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid,
nspOid, false, false, objsMoved);
/* Fix other dependent stuff */
- if (rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid, objsMoved);
- AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid,
- objsMoved, AccessExclusiveLock);
- AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid,
- false, objsMoved);
- }
+ AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid, objsMoved);
+ AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid,
+ objsMoved, AccessExclusiveLock);
+ AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid,
+ false, objsMoved);
table_close(classRel, RowExclusiveLock);
}
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 75b0ca9..329c73d 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1532,6 +1532,8 @@ vac_update_datfrozenxid(void)
/*
* We must seqscan pg_class to find the minimum Xid, because there is no
* index that can help us here.
+ *
+ * See vac_truncate_clog() for the race condition to prevent.
*/
relation = table_open(RelationRelationId, AccessShareLock);
@@ -1540,7 +1542,9 @@ vac_update_datfrozenxid(void)
while ((classTup = systable_getnext(scan)) != NULL)
{
- Form_pg_class classForm = (Form_pg_class) GETSTRUCT(classTup);
+ volatile FormData_pg_class *classForm = (Form_pg_class) GETSTRUCT(classTup);
+ TransactionId relfrozenxid = classForm->relfrozenxid;
+ TransactionId relminmxid = classForm->relminmxid;
/*
* Only consider relations able to hold unfrozen XIDs (anything else
@@ -1550,8 +1554,8 @@ vac_update_datfrozenxid(void)
classForm->relkind != RELKIND_MATVIEW &&
classForm->relkind != RELKIND_TOASTVALUE)
{
- Assert(!TransactionIdIsValid(classForm->relfrozenxid));
- Assert(!MultiXactIdIsValid(classForm->relminmxid));
+ Assert(!TransactionIdIsValid(relfrozenxid));
+ Assert(!MultiXactIdIsValid(relminmxid));
continue;
}
@@ -1570,34 +1574,34 @@ vac_update_datfrozenxid(void)
* before those relations have been scanned and cleaned up.
*/
- if (TransactionIdIsValid(classForm->relfrozenxid))
+ if (TransactionIdIsValid(relfrozenxid))
{
- Assert(TransactionIdIsNormal(classForm->relfrozenxid));
+ Assert(TransactionIdIsNormal(relfrozenxid));
/* check for values in the future */
- if (TransactionIdPrecedes(lastSaneFrozenXid, classForm->relfrozenxid))
+ if (TransactionIdPrecedes(lastSaneFrozenXid, relfrozenxid))
{
bogus = true;
break;
}
/* determine new horizon */
- if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid))
- newFrozenXid = classForm->relfrozenxid;
+ if (TransactionIdPrecedes(relfrozenxid, newFrozenXid))
+ newFrozenXid = relfrozenxid;
}
- if (MultiXactIdIsValid(classForm->relminmxid))
+ if (MultiXactIdIsValid(relminmxid))
{
/* check for values in the future */
- if (MultiXactIdPrecedes(lastSaneMinMulti, classForm->relminmxid))
+ if (MultiXactIdPrecedes(lastSaneMinMulti, relminmxid))
{
bogus = true;
break;
}
/* determine new horizon */
- if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti))
- newMinMulti = classForm->relminmxid;
+ if (MultiXactIdPrecedes(relminmxid, newMinMulti))
+ newMinMulti = relminmxid;
}
}