From f0640472cfabc960d1c07a6f596cccaaddbb9d41 Mon Sep 17 00:00:00 2001
From: satyanarayana narlapuram <satyanarlapuram@gmail.com>
Date: Tue, 21 Apr 2026 05:15:43 +0000
Subject: [PATCH] Block ALTER TABLE RENAME COLUMN when column is used by
 property graph

When a table column is referenced by a property graph, the property
name stored in pg_propgraph_property.pgpname would become stale after
a column rename.  This caused GRAPH_TABLE queries to fail with the new
column name ("property does not exist") while the old (dead) name
continued to work.  pg_get_propgraphdef() would also emit confusing
output like "new_col AS old_col".

Fix by checking pg_depend in renameatt_internal() for
PropgraphLabelPropertyRelationId entries that reference the column
being renamed.  If any exist, raise an error directing the user to
drop the property graph first.

This is consistent with how DROP COLUMN already blocks when a property
graph depends on the column.
---
 src/backend/commands/tablecmds.c              | 53 +++++++++++++++++++
 .../expected/create_property_graph.out        | 17 ++++++
 .../regress/sql/create_property_graph.sql     | 16 ++++++
 3 files changed, 86 insertions(+)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index eec09ba1..78b6e467 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -48,6 +48,7 @@
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_policy.h"
 #include "catalog/pg_proc.h"
+#include "catalog/pg_propgraph_label_property.h"
 #include "catalog/pg_publication_rel.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_statistic_ext.h"
@@ -3997,6 +3998,58 @@ renameatt_internal(Oid myrelid,
 	/* new name should not already exist */
 	(void) check_for_column_name_collision(targetrelation, newattname, false);
 
+	/*
+	 * Disallow renaming columns that are used by a property graph.  The
+	 * property graph catalog stores the property name in
+	 * pg_propgraph_property.pgpname, which would become stale after a
+	 * rename, causing GRAPH_TABLE queries using the new column name to fail
+	 * while the old (dead) name would still work.
+	 */
+	{
+		Relation	depRel;
+		ScanKeyData key[3];
+		SysScanDesc depScan;
+		HeapTuple	depTup;
+
+		depRel = table_open(DependRelationId, AccessShareLock);
+
+		ScanKeyInit(&key[0],
+					Anum_pg_depend_refclassid,
+					BTEqualStrategyNumber, F_OIDEQ,
+					ObjectIdGetDatum(RelationRelationId));
+		ScanKeyInit(&key[1],
+					Anum_pg_depend_refobjid,
+					BTEqualStrategyNumber, F_OIDEQ,
+					ObjectIdGetDatum(myrelid));
+		ScanKeyInit(&key[2],
+					Anum_pg_depend_refobjsubid,
+					BTEqualStrategyNumber, F_INT4EQ,
+					Int32GetDatum((int32) attnum));
+
+		depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
+									 NULL, 3, key);
+
+		while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
+		{
+			Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(depTup);
+
+			if (depForm->classid == PropgraphLabelPropertyRelationId)
+			{
+				systable_endscan(depScan);
+				table_close(depRel, AccessShareLock);
+				ereport(ERROR,
+						(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
+						 errmsg("cannot rename column \"%s\" of table \"%s\" because a property graph depends on it",
+								oldattname,
+								RelationGetRelationName(targetrelation)),
+						 errhint("Drop the property graph first, then rename the column.")));
+			}
+		}
+
+		systable_endscan(depScan);
+		table_close(depRel, AccessShareLock);
+	}
+
 	/* apply the update */
 	namestrcpy(&(attform->attname), newattname);
 
diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out
index bc9a596e..a1d3e6a0 100644
--- a/src/test/regress/expected/create_property_graph.out
+++ b/src/test/regress/expected/create_property_graph.out
@@ -901,6 +901,23 @@ ERROR:  cannot add temporary element table to non-temporary property graph
 LINE 2:     ADD VERTEX TABLES (v2tmp KEY (m));
                                ^
 DETAIL:  Table "v2tmp" is a temporary table.
+-- ALTER TABLE RENAME COLUMN should be blocked when column is used by
+-- a property graph (the property graph catalog stores property names
+-- that would become stale after the rename)
+CREATE TABLE rename_test (id int PRIMARY KEY, val text);
+CREATE PROPERTY GRAPH g_rename VERTEX TABLES (rename_test KEY (id));
+ALTER TABLE rename_test RENAME COLUMN val TO new_val;  -- error
+ERROR:  cannot rename column "val" of table "rename_test" because a property graph depends on it
+HINT:  Drop the property graph first, then rename the column.
+ALTER TABLE rename_test RENAME COLUMN id TO new_id;  -- error (KEY column)
+ERROR:  cannot rename column "id" of table "rename_test" because a property graph depends on it
+HINT:  Drop the property graph first, then rename the column.
+-- renaming a column not used by the graph should still work
+ALTER TABLE rename_test ADD COLUMN extra int;
+ALTER TABLE rename_test RENAME COLUMN extra TO extra2;  -- ok
+ALTER TABLE rename_test DROP COLUMN extra2;
+DROP PROPERTY GRAPH g_rename;
+DROP TABLE rename_test;
 -- DROP, ALTER SET SCHEMA, ALTER PROPERTY GRAPH RENAME TO
 DROP TABLE g2;  -- error: wrong object type
 ERROR:  "g2" is not a table
diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql
index 241f93df..03096f5d 100644
--- a/src/test/regress/sql/create_property_graph.sql
+++ b/src/test/regress/sql/create_property_graph.sql
@@ -347,6 +347,22 @@ ALTER PROPERTY GRAPH g1
     ADD VERTEX TABLES (v2tmp KEY (m));  -- error
 
 
+-- ALTER TABLE RENAME COLUMN should be blocked when column is used by
+-- a property graph (the property graph catalog stores property names
+-- that would become stale after the rename)
+
+CREATE TABLE rename_test (id int PRIMARY KEY, val text);
+CREATE PROPERTY GRAPH g_rename VERTEX TABLES (rename_test KEY (id));
+ALTER TABLE rename_test RENAME COLUMN val TO new_val;  -- error
+ALTER TABLE rename_test RENAME COLUMN id TO new_id;  -- error (KEY column)
+-- renaming a column not used by the graph should still work
+ALTER TABLE rename_test ADD COLUMN extra int;
+ALTER TABLE rename_test RENAME COLUMN extra TO extra2;  -- ok
+ALTER TABLE rename_test DROP COLUMN extra2;
+DROP PROPERTY GRAPH g_rename;
+DROP TABLE rename_test;
+
+
 -- DROP, ALTER SET SCHEMA, ALTER PROPERTY GRAPH RENAME TO
 
 DROP TABLE g2;  -- error: wrong object type
-- 
2.43.0

