diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index cdd5006..e2d7447 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -664,6 +664,38 @@ RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
 }
 
 /*
+ * CheckNamespaceAccessNoError
+ * 		Returns true if the namespace in given qualified-name can be accessable
+ * 		by the current user. If no namespace is given in names, just returns
+ * 		true.
+ */
+bool
+CheckNamespaceAccessNoError(List *names)
+{
+	char *namespacename;
+	char *objectname;
+	Oid namespaceId;
+	AclResult	aclresult;
+
+	/* deconstruct the name list */
+	DeconstructQualifiedName(names, &namespacename, &objectname);
+
+	if (namespacename)
+	{
+		namespaceId = get_namespace_oid(namespacename, true);
+		if (!OidIsValid(namespaceId))
+			/* Namespace is invalid */
+			return false;
+		aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
+		if (aclresult != ACLCHECK_OK)
+			/* Namespace ACL is not ok */
+			return false;
+	}
+
+	return true;
+}
+
+/*
  * RelnameGetRelid
  *		Try to resolve an unqualified relation name.
  *		Returns OID if relation found in search path, else InvalidOid.
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 09cf0e1..ab9ebad 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -128,6 +128,8 @@ to_regproc(PG_FUNCTION_ARGS)
 	 * entries in the current search path.
 	 */
 	names = stringToQualifiedNameList(pro_name);
+	if (!CheckNamespaceAccessNoError(names))
+		PG_RETURN_NULL();
 	clist = FuncnameGetCandidates(names, -1, NIL, false, false, true);
 
 	if (clist == NULL || clist->next != NULL)
@@ -301,6 +303,8 @@ to_regprocedure(PG_FUNCTION_ARGS)
 	 * given argument types.    (There will not be more than one match.)
 	 */
 	parseNameAndArgTypes(pro_name, false, &names, &nargs, argtypes);
+	if (!CheckNamespaceAccessNoError(names))
+		PG_RETURN_NULL();
 
 	clist = FuncnameGetCandidates(names, nargs, NIL, false, false, true);
 
@@ -546,6 +550,8 @@ to_regoper(PG_FUNCTION_ARGS)
 	 * entries in the current search path.
 	 */
 	names = stringToQualifiedNameList(opr_name);
+	if (!CheckNamespaceAccessNoError(names))
+		PG_RETURN_NULL();
 	clist = OpernameGetCandidates(names, '\0', true);
 
 	if (clist == NULL || clist->next != NULL)
@@ -736,6 +742,8 @@ to_regoperator(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
 				 errmsg("too many arguments"),
 				 errhint("Provide two argument types for operator.")));
+	if (!CheckNamespaceAccessNoError(names))
+		PG_RETURN_NULL();
 
 	result = OpernameGetOprid(names, argtypes[0], argtypes[1]);
 
@@ -948,13 +956,15 @@ to_regclass(PG_FUNCTION_ARGS)
 {
 	char	   *class_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
 	Oid			result;
-	List	   *names;
+	List		*names;
 
 	/*
 	 * Parse the name into components and see if it matches any pg_class
 	 * entries in the current search path.
 	 */
 	names = stringToQualifiedNameList(class_name);
+	if (!CheckNamespaceAccessNoError(names))
+		PG_RETURN_NULL();
 
 	/* We might not even have permissions on this relation; don't lock it. */
 	result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true);
@@ -1104,10 +1114,14 @@ to_regtype(PG_FUNCTION_ARGS)
 	char	   *typ_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
 	Oid			result;
 	int32		typmod;
+	List	   *names;
 
 	/*
 	 * Invoke the full parser to deal with special cases such as array syntax.
 	 */
+	names = stringToQualifiedNameList(typ_name);
+	if (!CheckNamespaceAccessNoError(names))
+		PG_RETURN_NULL();
 	parseTypeString(typ_name, &result, &typmod, true);
 
 	if (OidIsValid(result))
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 6741834..5507da3 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -73,6 +73,7 @@ extern Oid RangeVarGetAndCheckCreationNamespace(RangeVar *newRelation,
 									 LOCKMODE lockmode,
 									 Oid *existing_relation_id);
 extern void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid);
+extern bool CheckNamespaceAccessNoError(List *names);
 extern Oid	RelnameGetRelid(const char *relname);
 extern bool RelationIsVisible(Oid relid);
 
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index ee4fcda..bb00b31 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -395,3 +395,63 @@ SELECT to_regnamespace('"Nonexistent"');
 
 SELECT to_regnamespace('foo.bar');
 ERROR:  invalid name syntax
+/* If objects exist, and user don't have USAGE privilege, return NULL with no error. */
+CREATE USER test_usr;
+CREATE SCHEMA test_schema;
+REVOKE ALL ON SCHEMA test_schema FROM test_usr;
+CREATE OPERATOR  test_schema.+ (
+	leftarg = int8,
+	rightarg = int8,
+	procedure = int8pl
+);
+CREATE OR REPLACE FUNCTION test_schema.test_func(int)
+RETURNS INTEGER AS
+	'SELECT 1;'
+LANGUAGE sql;
+CREATE TABLE test_schema.test_tbl(id int);
+CREATE TYPE test_schema.test_type AS (a1 int,a2 int);
+SET SESSION AUTHORIZATION test_usr;
+SELECT to_regoper('test_schema.+');
+ to_regoper 
+------------
+ 
+(1 row)
+
+SELECT to_regoperator('test_schema.+(int8,int8)');
+ to_regoperator 
+----------------
+ 
+(1 row)
+
+SELECT to_regproc('test_schema.test_func');
+ to_regproc 
+------------
+ 
+(1 row)
+
+SELECT to_regprocedure('test_schema.test_func(int)');
+ to_regprocedure 
+-----------------
+ 
+(1 row)
+
+SELECT to_regclass('test_schema.test_tbl');
+ to_regclass 
+-------------
+ 
+(1 row)
+
+SELECT to_regtype('test_schema.test_type');
+ to_regtype 
+------------
+ 
+(1 row)
+
+RESET SESSION AUTHORIZATION;
+DROP SCHEMA test_schema CASCADE;
+NOTICE:  drop cascades to 4 other objects
+DETAIL:  drop cascades to operator test_schema.+(bigint,bigint)
+drop cascades to function test_schema.test_func(integer)
+drop cascades to table test_schema.test_tbl
+drop cascades to type test_schema.test_type
+DROP ROLE test_usr;
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index a60bc28..53e6c36 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -113,3 +113,33 @@ SELECT to_regrole('foo.bar');
 SELECT to_regnamespace('Nonexistent');
 SELECT to_regnamespace('"Nonexistent"');
 SELECT to_regnamespace('foo.bar');
+
+/* If objects exist, and user don't have USAGE privilege, return NULL with no error. */
+
+CREATE USER test_usr;
+CREATE SCHEMA test_schema;
+REVOKE ALL ON SCHEMA test_schema FROM test_usr;
+
+CREATE OPERATOR  test_schema.+ (
+	leftarg = int8,
+	rightarg = int8,
+	procedure = int8pl
+);
+CREATE OR REPLACE FUNCTION test_schema.test_func(int)
+RETURNS INTEGER AS
+	'SELECT 1;'
+LANGUAGE sql;
+CREATE TABLE test_schema.test_tbl(id int);
+CREATE TYPE test_schema.test_type AS (a1 int,a2 int);
+
+SET SESSION AUTHORIZATION test_usr;
+SELECT to_regoper('test_schema.+');
+SELECT to_regoperator('test_schema.+(int8,int8)');
+SELECT to_regproc('test_schema.test_func');
+SELECT to_regprocedure('test_schema.test_func(int)');
+SELECT to_regclass('test_schema.test_tbl');
+SELECT to_regtype('test_schema.test_type');
+RESET SESSION AUTHORIZATION;
+
+DROP SCHEMA test_schema CASCADE;
+DROP ROLE test_usr;
