From 55c3391d1e6a201b5b891781d21fe682a8c64fe6 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 13 Sep 2016 17:17:48 -0400
Subject: [PATCH] Be pickier about converting between Name and Datum.

We were misapplying NameGetDatum() to plain C strings in some places.
This worked, because it was just a pointer cast anyway, but it's a type
cheat in some sense.  Use CStringGetDatum instead, and modify the
NameGetDatum macro so it won't compile if applied to something that's
not a pointer to NameData.  This should result in no changes to
generated code, but it is logically cleaner.

Mark Dilger, tweaked a bit by me

Discussion: <EFD8AC94-4C1F-40C1-A5EA-304080089C1B@gmail.com>
---
 src/backend/commands/dbcommands.c | 8 ++++----
 src/backend/commands/proclang.c   | 2 +-
 src/backend/commands/typecmds.c   | 2 +-
 src/include/postgres.h            | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index ef486593c00..0919ad8dfe7 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -1260,7 +1260,7 @@ movedb(const char *dbname, const char *tblspcname)
 		ScanKeyInit(&scankey,
 					Anum_pg_database_datname,
 					BTEqualStrategyNumber, F_NAMEEQ,
-					NameGetDatum(dbname));
+					CStringGetDatum(dbname));
 		sysscan = systable_beginscan(pgdbrel, DatabaseNameIndexId, true,
 									 NULL, 1, &scankey);
 		oldtuple = systable_getnext(sysscan);
@@ -1486,7 +1486,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 	ScanKeyInit(&scankey,
 				Anum_pg_database_datname,
 				BTEqualStrategyNumber, F_NAMEEQ,
-				NameGetDatum(stmt->dbname));
+				CStringGetDatum(stmt->dbname));
 	scan = systable_beginscan(rel, DatabaseNameIndexId, true,
 							  NULL, 1, &scankey);
 	tuple = systable_getnext(scan);
@@ -1603,7 +1603,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
 	ScanKeyInit(&scankey,
 				Anum_pg_database_datname,
 				BTEqualStrategyNumber, F_NAMEEQ,
-				NameGetDatum(dbname));
+				CStringGetDatum(dbname));
 	scan = systable_beginscan(rel, DatabaseNameIndexId, true,
 							  NULL, 1, &scankey);
 	tuple = systable_getnext(scan);
@@ -1743,7 +1743,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
 		ScanKeyInit(&scanKey,
 					Anum_pg_database_datname,
 					BTEqualStrategyNumber, F_NAMEEQ,
-					NameGetDatum(name));
+					CStringGetDatum(name));
 
 		scan = systable_beginscan(relation, DatabaseNameIndexId, true,
 								  NULL, 1, &scanKey);
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 761d08f604b..4f870e8d300 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -463,7 +463,7 @@ find_language_template(const char *languageName)
 	ScanKeyInit(&key,
 				Anum_pg_pltemplate_tmplname,
 				BTEqualStrategyNumber, F_NAMEEQ,
-				NameGetDatum(languageName));
+				CStringGetDatum(languageName));
 	scan = systable_beginscan(rel, PLTemplateNameIndexId, true,
 							  NULL, 1, &key);
 
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 41fd2dae7f8..056933a5845 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3503,7 +3503,7 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
 
 		/* check for duplicate name (more friendly than unique-index failure) */
 		if (SearchSysCacheExists2(TYPENAMENSP,
-								  CStringGetDatum(NameStr(typform->typname)),
+								  NameGetDatum(&typform->typname),
 								  ObjectIdGetDatum(nspOid)))
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
diff --git a/src/include/postgres.h b/src/include/postgres.h
index d999013238a..be4d0d609ea 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -600,7 +600,7 @@ typedef Datum *DatumPtr;
  * value has adequate lifetime.
  */
 
-#define NameGetDatum(X) PointerGetDatum(X)
+#define NameGetDatum(X) CStringGetDatum(NameStr(*(X)))
 
 /*
  * DatumGetInt64
-- 
GitLab