From 42b041243c00fb20023c983357e7f1ffd3710fff Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 28 Apr 2024 14:34:21 -0400 Subject: [PATCH] Throw a more on-point error for functions depending on columns. ALTER COLUMN TYPE wasn't expecting to find any pg_proc objects depending on the column whose type is to be altered. That indeed wasn't possible when this code was written, but it is possible since we introduced new-style SQL function bodies. It's about as difficult to fix this case as it is to fix dependent views, and we've been punting on those for years, so I don't feel too awful about punting for functions too. (I sure wouldn't risk back-patching such code.) So just throw a more user-facing error. Also, adjust some of the existing comments to reflect that these are all pretty much the same issue. (This patch also fixes it so we will tolerate finding such a dependency during ALTER COLUMN SET EXPRESSION; in that, we need not do anything to the function, so no error is wanted. That problem is new in HEAD.) Per bug #18449 from Alexander Lakhin. Back-patch to v14 where we added new-style SQL functions. Discussion: https://postgr.es/m/18449-f8248467aaa294d5@postgresql.org --- src/backend/commands/tablecmds.c | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3556240c8e..f1725c9da8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -45,6 +45,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_policy.h" +#include "catalog/pg_proc.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_statistic_ext.h" #include "catalog/pg_tablespace.h" @@ -14094,8 +14095,33 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, RememberConstraintForRebuilding(foundObject.objectId, tab); break; + case ProcedureRelationId: + + /* + * 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. + * + * This is only a problem for AT_AlterColumnType, not + * AT_SetExpression. + */ + if (subtype == AT_AlterColumnType) + 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 RewriteRelationId: - /* XXX someday see if we can cope with revising views */ + + /* + * View/rule bodies have pretty much the same issues as + * function bodies. FIXME someday. + */ if (subtype == AT_AlterColumnType) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -14112,9 +14138,9 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, * 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. */ if (subtype == AT_AlterColumnType) ereport(ERROR,