On Sun, Sep  2, 2012 at 05:40:54PM +0000, ja...@illusorystudios.com wrote:
> The following bug has been logged on the website:
> 
> Bug reference:      7515
> Logged by:          James Bellinger
> Email address:      ja...@illusorystudios.com
> PostgreSQL version: 9.1.5
> Operating system:   Ubuntu Linux 12.04 Server
> Description:        
> 
> If the table being referenced has a schema in its name, and the schema does
> not exist, DROP TABLE IF EXISTS will have an ERROR instead of a NOTICE.
> 
> So for instance,
> DROP TABLE IF EXISTS bar;
> This is a NOTICE if bar does not exist.
> 
> DROP TABLE IF EXISTS foo.bar;
> This is an ERROR if foo does not exist, even though that implies bar does
> not exist which means it should be a NOTICE.
> 
> Saw this because it was making a drop/recreate transaction fail on me, after
> I changed some code to use a schema.

I looked at this bug report from September.  The problem is that
LookupExplicitNamespace() doesn't have a missing_ok parameter, even
though get_namespace_oid(), which it calls, does.  By adding a
missing_ok parameter and passing it cleanly, I fixed the problem:

        test=> DROP TABLE IF EXISTS foo.bar;
        NOTICE:  table "bar" does not exist, skipping
        DROP TABLE

Patch attached.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
new file mode 100644
index 0bf5356..b3f5ba0
*** a/src/backend/catalog/aclchk.c
--- b/src/backend/catalog/aclchk.c
*************** objectsInSchemaToOids(GrantObjectType ob
*** 755,761 ****
  		Oid			namespaceId;
  		List	   *objs;
  
! 		namespaceId = LookupExplicitNamespace(nspname);
  
  		switch (objtype)
  		{
--- 755,761 ----
  		Oid			namespaceId;
  		List	   *objs;
  
! 		namespaceId = LookupExplicitNamespace(nspname, false);
  
  		switch (objtype)
  		{
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
new file mode 100644
index b256498..8060807
*** a/src/backend/catalog/namespace.c
--- b/src/backend/catalog/namespace.c
*************** RangeVarGetRelidExtended(const RangeVar
*** 291,297 ****
  				{
  					Oid			namespaceId;
  
! 					namespaceId = LookupExplicitNamespace(relation->schemaname);
  					if (namespaceId != myTempNamespace)
  						ereport(ERROR,
  								(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
--- 291,301 ----
  				{
  					Oid			namespaceId;
  
! 					namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
! 					/*
! 					 *	For missing_ok, allow a non-existant schema name
! 					 *	to throw the error below (namespaceId == InvalidOid).
! 					 */
  					if (namespaceId != myTempNamespace)
  						ereport(ERROR,
  								(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
*************** RangeVarGetRelidExtended(const RangeVar
*** 306,313 ****
  			Oid			namespaceId;
  
  			/* use exact schema given */
! 			namespaceId = LookupExplicitNamespace(relation->schemaname);
! 			relId = get_relname_relid(relation->relname, namespaceId);
  		}
  		else
  		{
--- 310,320 ----
  			Oid			namespaceId;
  
  			/* use exact schema given */
! 			namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
! 			if (missing_ok && !OidIsValid(namespaceId))
! 				relId = InvalidOid;
! 			else
! 				relId = get_relname_relid(relation->relname, namespaceId);
  		}
  		else
  		{
*************** FuncnameGetCandidates(List *names, int n
*** 919,925 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
  	}
  	else
  	{
--- 926,932 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, false);
  	}
  	else
  	{
*************** OpernameGetOprid(List *names, Oid oprlef
*** 1453,1459 ****
  		Oid			namespaceId;
  		HeapTuple	opertup;
  
! 		namespaceId = LookupExplicitNamespace(schemaname);
  		opertup = SearchSysCache4(OPERNAMENSP,
  								  CStringGetDatum(opername),
  								  ObjectIdGetDatum(oprleft),
--- 1460,1466 ----
  		Oid			namespaceId;
  		HeapTuple	opertup;
  
! 		namespaceId = LookupExplicitNamespace(schemaname, false);
  		opertup = SearchSysCache4(OPERNAMENSP,
  								  CStringGetDatum(opername),
  								  ObjectIdGetDatum(oprleft),
*************** OpernameGetCandidates(List *names, char
*** 1551,1557 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
  	}
  	else
  	{
--- 1558,1564 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, false);
  	}
  	else
  	{
*************** get_ts_parser_oid(List *names, bool miss
*** 2093,2102 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
! 		prsoid = GetSysCacheOid2(TSPARSERNAMENSP,
! 								 PointerGetDatum(parser_name),
! 								 ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
--- 2100,2112 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
! 		if (missing_ok && !OidIsValid(namespaceId))
! 			prsoid = InvalidOid;
! 		else
! 			prsoid = GetSysCacheOid2(TSPARSERNAMENSP,
! 									 PointerGetDatum(parser_name),
! 									 ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
*************** get_ts_dict_oid(List *names, bool missin
*** 2216,2225 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
! 		dictoid = GetSysCacheOid2(TSDICTNAMENSP,
! 								  PointerGetDatum(dict_name),
! 								  ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
--- 2226,2238 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
! 		if (missing_ok && !OidIsValid(namespaceId))
! 			dictoid = InvalidOid;
! 		else
! 			dictoid = GetSysCacheOid2(TSDICTNAMENSP,
! 									  PointerGetDatum(dict_name),
! 									  ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
*************** get_ts_template_oid(List *names, bool mi
*** 2340,2349 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
! 		tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP,
! 								  PointerGetDatum(template_name),
! 								  ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
--- 2353,2365 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
! 		if (missing_ok && !OidIsValid(namespaceId))
! 			tmploid = InvalidOid;
! 		else
! 			tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP,
! 									  PointerGetDatum(template_name),
! 									  ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
*************** get_ts_config_oid(List *names, bool miss
*** 2463,2472 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
! 		cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP,
! 								 PointerGetDatum(config_name),
! 								 ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
--- 2479,2491 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
! 		if (missing_ok && !OidIsValid(namespaceId))
! 			cfgoid = InvalidOid;
! 		else
! 			cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP,
! 									 PointerGetDatum(config_name),
! 									 ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
*************** LookupNamespaceNoError(const char *nspna
*** 2657,2663 ****
   * Returns the namespace OID.  Raises ereport if any problem.
   */
  Oid
! LookupExplicitNamespace(const char *nspname)
  {
  	Oid			namespaceId;
  	AclResult	aclresult;
--- 2676,2682 ----
   * Returns the namespace OID.  Raises ereport if any problem.
   */
  Oid
! LookupExplicitNamespace(const char *nspname, bool missing_ok)
  {
  	Oid			namespaceId;
  	AclResult	aclresult;
*************** LookupExplicitNamespace(const char *nspn
*** 2676,2683 ****
  		 */
  	}
  
! 	namespaceId = get_namespace_oid(nspname, false);
! 
  	aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
  	if (aclresult != ACLCHECK_OK)
  		aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
--- 2695,2704 ----
  		 */
  	}
  
! 	namespaceId = get_namespace_oid(nspname, missing_ok);
! 	if (missing_ok && !OidIsValid(namespaceId))
! 		return InvalidOid;
! 	
  	aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
  	if (aclresult != ACLCHECK_OK)
  		aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
*************** get_collation_oid(List *name, bool missi
*** 3226,3232 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
  
  		/* first try for encoding-specific entry, then any-encoding */
  		colloid = GetSysCacheOid3(COLLNAMEENCNSP,
--- 3247,3255 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
! 		if (missing_ok && !OidIsValid(namespaceId))
! 			return InvalidOid;
  
  		/* first try for encoding-specific entry, then any-encoding */
  		colloid = GetSysCacheOid3(COLLNAMEENCNSP,
*************** get_conversion_oid(List *name, bool miss
*** 3296,3305 ****
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname);
! 		conoid = GetSysCacheOid2(CONNAMENSP,
! 								 PointerGetDatum(conversion_name),
! 								 ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
--- 3319,3331 ----
  	if (schemaname)
  	{
  		/* use exact schema given */
! 		namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
! 		if (missing_ok && !OidIsValid(namespaceId))
! 			conoid = InvalidOid;
! 		else
! 			conoid = GetSysCacheOid2(CONNAMENSP,
! 									 PointerGetDatum(conversion_name),
! 									 ObjectIdGetDatum(namespaceId));
  	}
  	else
  	{
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
new file mode 100644
index 94efd13..c3385a1
*** a/src/backend/commands/indexcmds.c
--- b/src/backend/commands/indexcmds.c
*************** GetIndexOpClass(List *opclass, Oid attrT
*** 1264,1270 ****
  		/* Look in specific schema only */
  		Oid			namespaceId;
  
! 		namespaceId = LookupExplicitNamespace(schemaname);
  		tuple = SearchSysCache3(CLAAMNAMENSP,
  								ObjectIdGetDatum(accessMethodId),
  								PointerGetDatum(opcname),
--- 1264,1270 ----
  		/* Look in specific schema only */
  		Oid			namespaceId;
  
! 		namespaceId = LookupExplicitNamespace(schemaname, false);
  		tuple = SearchSysCache3(CLAAMNAMENSP,
  								ObjectIdGetDatum(accessMethodId),
  								PointerGetDatum(opcname),
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
new file mode 100644
index 2cfd89a..95b9a73
*** a/src/backend/commands/opclasscmds.c
--- b/src/backend/commands/opclasscmds.c
*************** OpFamilyCacheLookup(Oid amID, List *opfa
*** 103,109 ****
  		/* Look in specific schema only */
  		Oid			namespaceId;
  
! 		namespaceId = LookupExplicitNamespace(schemaname);
  		htup = SearchSysCache3(OPFAMILYAMNAMENSP,
  							   ObjectIdGetDatum(amID),
  							   PointerGetDatum(opfname),
--- 103,109 ----
  		/* Look in specific schema only */
  		Oid			namespaceId;
  
! 		namespaceId = LookupExplicitNamespace(schemaname, false);
  		htup = SearchSysCache3(OPFAMILYAMNAMENSP,
  							   ObjectIdGetDatum(amID),
  							   PointerGetDatum(opfname),
*************** OpClassCacheLookup(Oid amID, List *opcla
*** 179,185 ****
  		/* Look in specific schema only */
  		Oid			namespaceId;
  
! 		namespaceId = LookupExplicitNamespace(schemaname);
  		htup = SearchSysCache3(CLAAMNAMENSP,
  							   ObjectIdGetDatum(amID),
  							   PointerGetDatum(opcname),
--- 179,185 ----
  		/* Look in specific schema only */
  		Oid			namespaceId;
  
! 		namespaceId = LookupExplicitNamespace(schemaname, false);
  		htup = SearchSysCache3(CLAAMNAMENSP,
  							   ObjectIdGetDatum(amID),
  							   PointerGetDatum(opcname),
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
new file mode 100644
index f11a8ec..c0322b7
*** a/src/backend/commands/trigger.c
--- b/src/backend/commands/trigger.c
*************** AfterTriggerSetState(ConstraintsSetStmt
*** 4226,4232 ****
  			 */
  			if (constraint->schemaname)
  			{
! 				Oid			namespaceId = LookupExplicitNamespace(constraint->schemaname);
  
  				namespacelist = list_make1_oid(namespaceId);
  			}
--- 4226,4233 ----
  			 */
  			if (constraint->schemaname)
  			{
! 				Oid			namespaceId = LookupExplicitNamespace(constraint->schemaname,
! 																  false);
  
  				namespacelist = list_make1_oid(namespaceId);
  			}
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
new file mode 100644
index 0f508a2..dd80fa9
*** a/src/backend/parser/parse_oper.c
--- b/src/backend/parser/parse_oper.c
*************** make_oper_cache_key(OprCacheKey *key, Li
*** 1027,1033 ****
  	if (schemaname)
  	{
  		/* search only in exact schema given */
! 		key->search_path[0] = LookupExplicitNamespace(schemaname);
  	}
  	else
  	{
--- 1027,1033 ----
  	if (schemaname)
  	{
  		/* search only in exact schema given */
! 		key->search_path[0] = LookupExplicitNamespace(schemaname, false);
  	}
  	else
  	{
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
new file mode 100644
index 22879a9..07fce8a
*** a/src/backend/parser/parse_type.c
--- b/src/backend/parser/parse_type.c
*************** LookupTypeName(ParseState *pstate, const
*** 149,155 ****
  			/* Look in specific schema only */
  			Oid			namespaceId;
  
! 			namespaceId = LookupExplicitNamespace(schemaname);
  			typoid = GetSysCacheOid2(TYPENAMENSP,
  									 PointerGetDatum(typname),
  									 ObjectIdGetDatum(namespaceId));
--- 149,155 ----
  			/* Look in specific schema only */
  			Oid			namespaceId;
  
! 			namespaceId = LookupExplicitNamespace(schemaname, false);
  			typoid = GetSysCacheOid2(TYPENAMENSP,
  									 PointerGetDatum(typname),
  									 ObjectIdGetDatum(namespaceId));
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
new file mode 100644
index 3473107..e101ea6
*** a/src/backend/utils/adt/xml.c
--- b/src/backend/utils/adt/xml.c
*************** schema_to_xml(PG_FUNCTION_ARGS)
*** 2678,2684 ****
  	Oid			nspid;
  
  	schemaname = NameStr(*name);
! 	nspid = LookupExplicitNamespace(schemaname);
  
  	PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, NULL,
  									   nulls, tableforest, targetns, true)));
--- 2678,2684 ----
  	Oid			nspid;
  
  	schemaname = NameStr(*name);
! 	nspid = LookupExplicitNamespace(schemaname, false);
  
  	PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, NULL,
  									   nulls, tableforest, targetns, true)));
*************** schema_to_xmlschema_internal(const char
*** 2724,2730 ****
  
  	result = makeStringInfo();
  
! 	nspid = LookupExplicitNamespace(schemaname);
  
  	xsd_schema_element_start(result, targetns);
  
--- 2724,2730 ----
  
  	result = makeStringInfo();
  
! 	nspid = LookupExplicitNamespace(schemaname, false);
  
  	xsd_schema_element_start(result, targetns);
  
*************** schema_to_xml_and_xmlschema(PG_FUNCTION_
*** 2782,2788 ****
  	StringInfo	xmlschema;
  
  	schemaname = NameStr(*name);
! 	nspid = LookupExplicitNamespace(schemaname);
  
  	xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
  											 tableforest, targetns);
--- 2782,2788 ----
  	StringInfo	xmlschema;
  
  	schemaname = NameStr(*name);
! 	nspid = LookupExplicitNamespace(schemaname, false);
  
  	xmlschema = schema_to_xmlschema_internal(schemaname, nulls,
  											 tableforest, targetns);
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
new file mode 100644
index af82072..12c035d
*** a/src/include/catalog/namespace.h
--- b/src/include/catalog/namespace.h
*************** extern void DeconstructQualifiedName(Lis
*** 106,112 ****
  						 char **nspname_p,
  						 char **objname_p);
  extern Oid	LookupNamespaceNoError(const char *nspname);
! extern Oid	LookupExplicitNamespace(const char *nspname);
  extern Oid	get_namespace_oid(const char *nspname, bool missing_ok);
  
  extern Oid	LookupCreationNamespace(const char *nspname);
--- 106,112 ----
  						 char **nspname_p,
  						 char **objname_p);
  extern Oid	LookupNamespaceNoError(const char *nspname);
! extern Oid	LookupExplicitNamespace(const char *nspname, bool missing_ok);
  extern Oid	get_namespace_oid(const char *nspname, bool missing_ok);
  
  extern Oid	LookupCreationNamespace(const char *nspname);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to