hash_create() can return a NULL pointer if an error occurs (principally,
when we're out of memory). Some of the call sites checked for this
condition, but some did not. This patch fixes the remaining call sites
to check the return value, and ereport(ERROR) if it is NULL.

I'm not really sure whether this is the correct fix, but it certainly
seems wrong to be doing the check in some places and not in others.
Another approach would be to elog(ERROR) when an error occurs in
hash_create(), which would be fine except there might be some
circumstances in which hash_create() is invoked but elog(ERROR) is not
setup yet.

Comments?

-Neil

(Patch attached as a unified diff -- apologies for that, but I'm playing
with a new version control tool that most easily emits unified diffs.
http://www.venge.net/monotone/, if you're curious.)
--- contrib/tablefunc/tablefunc.c
+++ contrib/tablefunc/tablefunc.c
@@ -771,6 +771,11 @@
 	 */
 	crosstab_HashTable = hash_create("crosstab hash", INIT_CATS, &ctl, HASH_ELEM);
 
+	if (crosstab_HashTable == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
+
 	/* Connect to SPI manager */
 	if ((ret = SPI_connect()) < 0)
 		/* internal error */
--- src/backend/access/transam/xlogutils.c
+++ src/backend/access/transam/xlogutils.c
@@ -109,6 +109,11 @@
 
 	_xlrelcache = hash_create("XLOG relcache", _XLOG_RELCACHESIZE,
 							  &ctl, HASH_ELEM | HASH_FUNCTION);
+
+	if (_xlrelcache == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
 }
 
 static void
--- src/backend/storage/smgr/smgr.c
+++ src/backend/storage/smgr/smgr.c
@@ -201,6 +201,11 @@
 		ctl.hash = tag_hash;
 		SMgrRelationHash = hash_create("smgr relation table", 400,
 									   &ctl, HASH_ELEM | HASH_FUNCTION);
+		if (SMgrRelationHash == NULL)
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory")));
+
 	}
 
 	/* Look up or create an entry */
--- src/backend/utils/adt/ri_triggers.c
+++ src/backend/utils/adt/ri_triggers.c
@@ -3413,6 +3413,10 @@
 	ctl.hash = tag_hash;
 	ri_query_cache = hash_create("RI query cache", RI_INIT_QUERYHASHSIZE,
 								 &ctl, HASH_ELEM | HASH_FUNCTION);
+	if (ri_query_cache == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
 }
 
 
--- src/backend/utils/cache/relcache.c
+++ src/backend/utils/cache/relcache.c
@@ -1119,6 +1119,10 @@
 		ctl.hash = tag_hash;
 		OpClassCache = hash_create("Operator class cache", 64,
 								   &ctl, HASH_ELEM | HASH_FUNCTION);
+		if (OpClassCache == NULL)
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory")));
 	}
 
 	opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
@@ -2307,12 +2311,20 @@
 	ctl.entrysize = sizeof(RelNameCacheEnt);
 	RelationSysNameCache = hash_create("Relcache by name", INITRELCACHESIZE,
 									   &ctl, HASH_ELEM);
+	if (RelationSysNameCache == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
 
 	ctl.keysize = sizeof(Oid);
 	ctl.entrysize = sizeof(RelIdCacheEnt);
 	ctl.hash = tag_hash;
 	RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE,
 								  &ctl, HASH_ELEM | HASH_FUNCTION);
+	if (RelationIdCache == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
 
 	/*
 	 * Try to load the relcache cache file.  If successful, we're done for
--- src/backend/utils/cache/typcache.c
+++ src/backend/utils/cache/typcache.c
@@ -127,6 +127,10 @@
 		ctl.hash = tag_hash;
 		TypeCacheHash = hash_create("Type information cache", 64,
 									&ctl, HASH_ELEM | HASH_FUNCTION);
+		if (TypeCacheHash == NULL)
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory")));
 	}
 
 	/* Try to look up an existing entry */
@@ -468,6 +472,10 @@
 		ctl.hash = tag_hash;
 		RecordCacheHash = hash_create("Record information cache", 64,
 									  &ctl, HASH_ELEM | HASH_FUNCTION);
+		if (RecordCacheHash == NULL)
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of memory")));
 	}
 
 	/* Find or create a hashtable entry for this hash class */
--- src/backend/utils/mmgr/portalmem.c
+++ src/backend/utils/mmgr/portalmem.c
@@ -126,6 +126,11 @@
 	 */
 	PortalHashTable = hash_create("Portal hash", PORTALS_PER_USER,
 								  &ctl, HASH_ELEM);
+
+	if (PortalHashTable == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
 }
 
 /*
--- src/pl/plpgsql/src/pl_comp.c
+++ src/pl/plpgsql/src/pl_comp.c
@@ -1944,6 +1944,10 @@
 									FUNCS_PER_USER,
 									&ctl,
 									HASH_ELEM | HASH_FUNCTION);
+	if (plpgsql_HashTable == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("out of memory")));
 }
 
 static PLpgSQL_function *
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Reply via email to