From 7e2322dff30c04d90c0602d2b5ae24b4881db88b Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sat, 26 Jan 2013 13:24:50 -0500 Subject: [PATCH] Allow CREATE TABLE IF EXIST so succeed if the schema is nonexistent Previously, CREATE TABLE IF EXIST threw an error if the schema was nonexistent. This was done by passing 'missing_ok' to the function that looks up the schema oid. --- src/backend/catalog/aclchk.c | 2 +- src/backend/catalog/namespace.c | 86 +++++++++++++++++++----------- src/backend/commands/indexcmds.c | 2 +- src/backend/commands/opclasscmds.c | 4 +- src/backend/commands/trigger.c | 3 +- src/backend/parser/parse_oper.c | 2 +- src/backend/parser/parse_type.c | 2 +- src/backend/utils/adt/xml.c | 6 +-- src/include/catalog/namespace.h | 2 +- 9 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 0bf53561de..b3f5ba0e6e 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -755,7 +755,7 @@ objectsInSchemaToOids(GrantObjectType objtype, List *nspnames) Oid namespaceId; List *objs; - namespaceId = LookupExplicitNamespace(nspname); + namespaceId = LookupExplicitNamespace(nspname, false); switch (objtype) { diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index ca4635dc51..1c76602b5e 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -291,7 +291,11 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, { Oid namespaceId; - namespaceId = LookupExplicitNamespace(relation->schemaname); + 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), @@ -306,8 +310,11 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, Oid namespaceId; /* use exact schema given */ - namespaceId = LookupExplicitNamespace(relation->schemaname); - relId = get_relname_relid(relation->relname, namespaceId); + namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok); + if (missing_ok && !OidIsValid(namespaceId)) + relId = InvalidOid; + else + relId = get_relname_relid(relation->relname, namespaceId); } else { @@ -919,7 +926,7 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); + namespaceId = LookupExplicitNamespace(schemaname, false); } else { @@ -1453,7 +1460,7 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright) Oid namespaceId; HeapTuple opertup; - namespaceId = LookupExplicitNamespace(schemaname); + namespaceId = LookupExplicitNamespace(schemaname, false); opertup = SearchSysCache4(OPERNAMENSP, CStringGetDatum(opername), ObjectIdGetDatum(oprleft), @@ -1551,7 +1558,7 @@ OpernameGetCandidates(List *names, char oprkind) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); + namespaceId = LookupExplicitNamespace(schemaname, false); } else { @@ -2093,10 +2100,13 @@ get_ts_parser_oid(List *names, bool missing_ok) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); - prsoid = GetSysCacheOid2(TSPARSERNAMENSP, - PointerGetDatum(parser_name), - ObjectIdGetDatum(namespaceId)); + namespaceId = LookupExplicitNamespace(schemaname, missing_ok); + if (missing_ok && !OidIsValid(namespaceId)) + prsoid = InvalidOid; + else + prsoid = GetSysCacheOid2(TSPARSERNAMENSP, + PointerGetDatum(parser_name), + ObjectIdGetDatum(namespaceId)); } else { @@ -2216,10 +2226,13 @@ get_ts_dict_oid(List *names, bool missing_ok) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); - dictoid = GetSysCacheOid2(TSDICTNAMENSP, - PointerGetDatum(dict_name), - ObjectIdGetDatum(namespaceId)); + namespaceId = LookupExplicitNamespace(schemaname, missing_ok); + if (missing_ok && !OidIsValid(namespaceId)) + dictoid = InvalidOid; + else + dictoid = GetSysCacheOid2(TSDICTNAMENSP, + PointerGetDatum(dict_name), + ObjectIdGetDatum(namespaceId)); } else { @@ -2340,10 +2353,13 @@ get_ts_template_oid(List *names, bool missing_ok) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); - tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, - PointerGetDatum(template_name), - ObjectIdGetDatum(namespaceId)); + namespaceId = LookupExplicitNamespace(schemaname, missing_ok); + if (missing_ok && !OidIsValid(namespaceId)) + tmploid = InvalidOid; + else + tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, + PointerGetDatum(template_name), + ObjectIdGetDatum(namespaceId)); } else { @@ -2463,10 +2479,13 @@ get_ts_config_oid(List *names, bool missing_ok) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); - cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, - PointerGetDatum(config_name), - ObjectIdGetDatum(namespaceId)); + namespaceId = LookupExplicitNamespace(schemaname, missing_ok); + if (missing_ok && !OidIsValid(namespaceId)) + cfgoid = InvalidOid; + else + cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, + PointerGetDatum(config_name), + ObjectIdGetDatum(namespaceId)); } else { @@ -2657,7 +2676,7 @@ LookupNamespaceNoError(const char *nspname) * Returns the namespace OID. Raises ereport if any problem. */ Oid -LookupExplicitNamespace(const char *nspname) +LookupExplicitNamespace(const char *nspname, bool missing_ok) { Oid namespaceId; AclResult aclresult; @@ -2676,8 +2695,10 @@ LookupExplicitNamespace(const char *nspname) */ } - namespaceId = get_namespace_oid(nspname, false); - + 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, @@ -3248,7 +3269,9 @@ get_collation_oid(List *name, bool missing_ok) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); + namespaceId = LookupExplicitNamespace(schemaname, missing_ok); + if (missing_ok && !OidIsValid(namespaceId)) + return InvalidOid; /* first try for encoding-specific entry, then any-encoding */ colloid = GetSysCacheOid3(COLLNAMEENCNSP, @@ -3318,10 +3341,13 @@ get_conversion_oid(List *name, bool missing_ok) if (schemaname) { /* use exact schema given */ - namespaceId = LookupExplicitNamespace(schemaname); - conoid = GetSysCacheOid2(CONNAMENSP, - PointerGetDatum(conversion_name), - ObjectIdGetDatum(namespaceId)); + 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 index 94efd13989..c3385a113a 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1264,7 +1264,7 @@ GetIndexOpClass(List *opclass, Oid attrType, /* Look in specific schema only */ Oid namespaceId; - namespaceId = LookupExplicitNamespace(schemaname); + 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 index 2cfd89a7f9..95b9a738fe 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -103,7 +103,7 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname, bool missing_ok) /* Look in specific schema only */ Oid namespaceId; - namespaceId = LookupExplicitNamespace(schemaname); + namespaceId = LookupExplicitNamespace(schemaname, false); htup = SearchSysCache3(OPFAMILYAMNAMENSP, ObjectIdGetDatum(amID), PointerGetDatum(opfname), @@ -179,7 +179,7 @@ OpClassCacheLookup(Oid amID, List *opclassname, bool missing_ok) /* Look in specific schema only */ Oid namespaceId; - namespaceId = LookupExplicitNamespace(schemaname); + 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 index f11a8ec5d4..c0322b7bec 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -4226,7 +4226,8 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) */ if (constraint->schemaname) { - Oid namespaceId = LookupExplicitNamespace(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 index 0f508a2010..dd80fa9f95 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -1027,7 +1027,7 @@ make_oper_cache_key(OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId) if (schemaname) { /* search only in exact schema given */ - key->search_path[0] = LookupExplicitNamespace(schemaname); + key->search_path[0] = LookupExplicitNamespace(schemaname, false); } else { diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c index 22879a97f6..07fce8a011 100644 --- a/src/backend/parser/parse_type.c +++ b/src/backend/parser/parse_type.c @@ -149,7 +149,7 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, /* Look in specific schema only */ Oid namespaceId; - namespaceId = LookupExplicitNamespace(schemaname); + 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 index 3473107160..e101ea6349 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -2678,7 +2678,7 @@ schema_to_xml(PG_FUNCTION_ARGS) Oid nspid; schemaname = NameStr(*name); - nspid = LookupExplicitNamespace(schemaname); + nspid = LookupExplicitNamespace(schemaname, false); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, NULL, nulls, tableforest, targetns, true))); @@ -2724,7 +2724,7 @@ schema_to_xmlschema_internal(const char *schemaname, bool nulls, result = makeStringInfo(); - nspid = LookupExplicitNamespace(schemaname); + nspid = LookupExplicitNamespace(schemaname, false); xsd_schema_element_start(result, targetns); @@ -2782,7 +2782,7 @@ schema_to_xml_and_xmlschema(PG_FUNCTION_ARGS) StringInfo xmlschema; schemaname = NameStr(*name); - nspid = LookupExplicitNamespace(schemaname); + 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 index c37df8686e..4fadc746a8 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -106,7 +106,7 @@ extern void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p); extern Oid LookupNamespaceNoError(const char *nspname); -extern Oid LookupExplicitNamespace(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);