Centralize code for interpreting schema references, which had gotten
copied more places than I first thought it would. This fixes a bug: a couple of these places were neglecting to enforce USAGE access on explicitly-referenced schemas.
This commit is contained in:
parent
7b970bc1bc
commit
b5eebc1fd4
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.26 2002/07/20 05:16:56 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.27 2002/07/29 23:46:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -164,18 +164,7 @@ RangeVarGetRelid(const RangeVar *relation, bool failOK)
|
|||||||
if (relation->schemaname)
|
if (relation->schemaname)
|
||||||
{
|
{
|
||||||
/* use exact schema given */
|
/* use exact schema given */
|
||||||
AclResult aclresult;
|
namespaceId = LookupExplicitNamespace(relation->schemaname);
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
|
||||||
CStringGetDatum(relation->schemaname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(namespaceId))
|
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
|
||||||
relation->schemaname);
|
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
|
|
||||||
if (aclresult != ACLCHECK_OK)
|
|
||||||
aclcheck_error(aclresult, relation->schemaname);
|
|
||||||
|
|
||||||
relId = get_relname_relid(relation->relname, namespaceId);
|
relId = get_relname_relid(relation->relname, namespaceId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -239,6 +228,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
|
|||||||
if (!OidIsValid(namespaceId))
|
if (!OidIsValid(namespaceId))
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
elog(ERROR, "Namespace \"%s\" does not exist",
|
||||||
newRelation->schemaname);
|
newRelation->schemaname);
|
||||||
|
/* we do not check for USAGE rights here! */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -431,53 +421,19 @@ FuncCandidateList
|
|||||||
FuncnameGetCandidates(List *names, int nargs)
|
FuncnameGetCandidates(List *names, int nargs)
|
||||||
{
|
{
|
||||||
FuncCandidateList resultList = NULL;
|
FuncCandidateList resultList = NULL;
|
||||||
char *catalogname;
|
char *schemaname;
|
||||||
char *schemaname = NULL;
|
char *funcname;
|
||||||
char *funcname = NULL;
|
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
CatCList *catlist;
|
CatCList *catlist;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* deconstruct the name list */
|
/* deconstruct the name list */
|
||||||
switch (length(names))
|
DeconstructQualifiedName(names, &schemaname, &funcname);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
funcname = strVal(lfirst(names));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
schemaname = strVal(lfirst(names));
|
|
||||||
funcname = strVal(lsecond(names));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
catalogname = strVal(lfirst(names));
|
|
||||||
schemaname = strVal(lsecond(names));
|
|
||||||
funcname = strVal(lfirst(lnext(lnext(names))));
|
|
||||||
/*
|
|
||||||
* We check the catalog name and then ignore it.
|
|
||||||
*/
|
|
||||||
if (strcmp(catalogname, DatabaseName) != 0)
|
|
||||||
elog(ERROR, "Cross-database references are not implemented");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "Improper qualified name (too many dotted names): %s",
|
|
||||||
NameListToString(names));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (schemaname)
|
if (schemaname)
|
||||||
{
|
{
|
||||||
/* use exact schema given */
|
/* use exact schema given */
|
||||||
AclResult aclresult;
|
namespaceId = LookupExplicitNamespace(schemaname);
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
|
||||||
CStringGetDatum(schemaname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(namespaceId))
|
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
|
||||||
schemaname);
|
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
|
|
||||||
if (aclresult != ACLCHECK_OK)
|
|
||||||
aclcheck_error(aclresult, schemaname);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -684,53 +640,19 @@ FuncCandidateList
|
|||||||
OpernameGetCandidates(List *names, char oprkind)
|
OpernameGetCandidates(List *names, char oprkind)
|
||||||
{
|
{
|
||||||
FuncCandidateList resultList = NULL;
|
FuncCandidateList resultList = NULL;
|
||||||
char *catalogname;
|
char *schemaname;
|
||||||
char *schemaname = NULL;
|
char *opername;
|
||||||
char *opername = NULL;
|
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
CatCList *catlist;
|
CatCList *catlist;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* deconstruct the name list */
|
/* deconstruct the name list */
|
||||||
switch (length(names))
|
DeconstructQualifiedName(names, &schemaname, &opername);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
opername = strVal(lfirst(names));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
schemaname = strVal(lfirst(names));
|
|
||||||
opername = strVal(lsecond(names));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
catalogname = strVal(lfirst(names));
|
|
||||||
schemaname = strVal(lsecond(names));
|
|
||||||
opername = strVal(lfirst(lnext(lnext(names))));
|
|
||||||
/*
|
|
||||||
* We check the catalog name and then ignore it.
|
|
||||||
*/
|
|
||||||
if (strcmp(catalogname, DatabaseName) != 0)
|
|
||||||
elog(ERROR, "Cross-database references are not implemented");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "Improper qualified name (too many dotted names): %s",
|
|
||||||
NameListToString(names));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (schemaname)
|
if (schemaname)
|
||||||
{
|
{
|
||||||
/* use exact schema given */
|
/* use exact schema given */
|
||||||
AclResult aclresult;
|
namespaceId = LookupExplicitNamespace(schemaname);
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
|
||||||
CStringGetDatum(schemaname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(namespaceId))
|
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
|
||||||
schemaname);
|
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
|
|
||||||
if (aclresult != ACLCHECK_OK)
|
|
||||||
aclcheck_error(aclresult, schemaname);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1105,25 +1027,22 @@ OpclassIsVisible(Oid opcid)
|
|||||||
return visible;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifiedNameGetCreationNamespace
|
* DeconstructQualifiedName
|
||||||
* Given a possibly-qualified name for an object (in List-of-Values
|
* Given a possibly-qualified name expressed as a list of String nodes,
|
||||||
* format), determine what namespace the object should be created in.
|
* extract the schema name and object name.
|
||||||
* Also extract and return the object name (last component of list).
|
|
||||||
*
|
*
|
||||||
* This is *not* used for tables. Hence, the TEMP table namespace is
|
* *nspname_p is set to NULL if there is no explicit schema name.
|
||||||
* never selected as the creation target.
|
|
||||||
*/
|
*/
|
||||||
Oid
|
void
|
||||||
QualifiedNameGetCreationNamespace(List *names, char **objname_p)
|
DeconstructQualifiedName(List *names,
|
||||||
|
char **nspname_p,
|
||||||
|
char **objname_p)
|
||||||
{
|
{
|
||||||
char *catalogname;
|
char *catalogname;
|
||||||
char *schemaname = NULL;
|
char *schemaname = NULL;
|
||||||
char *objname = NULL;
|
char *objname = NULL;
|
||||||
Oid namespaceId;
|
|
||||||
|
|
||||||
/* deconstruct the name list */
|
|
||||||
switch (length(names))
|
switch (length(names))
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@ -1149,6 +1068,55 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*nspname_p = schemaname;
|
||||||
|
*objname_p = objname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LookupExplicitNamespace
|
||||||
|
* Process an explicitly-specified schema name: look up the schema
|
||||||
|
* and verify we have USAGE (lookup) rights in it.
|
||||||
|
*
|
||||||
|
* Returns the namespace OID. Raises elog if any problem.
|
||||||
|
*/
|
||||||
|
Oid
|
||||||
|
LookupExplicitNamespace(char *nspname)
|
||||||
|
{
|
||||||
|
Oid namespaceId;
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
|
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
||||||
|
CStringGetDatum(nspname),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!OidIsValid(namespaceId))
|
||||||
|
elog(ERROR, "Namespace \"%s\" does not exist", nspname);
|
||||||
|
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, nspname);
|
||||||
|
|
||||||
|
return namespaceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QualifiedNameGetCreationNamespace
|
||||||
|
* Given a possibly-qualified name for an object (in List-of-Values
|
||||||
|
* format), determine what namespace the object should be created in.
|
||||||
|
* Also extract and return the object name (last component of list).
|
||||||
|
*
|
||||||
|
* This is *not* used for tables. Hence, the TEMP table namespace is
|
||||||
|
* never selected as the creation target.
|
||||||
|
*/
|
||||||
|
Oid
|
||||||
|
QualifiedNameGetCreationNamespace(List *names, char **objname_p)
|
||||||
|
{
|
||||||
|
char *schemaname;
|
||||||
|
char *objname;
|
||||||
|
Oid namespaceId;
|
||||||
|
|
||||||
|
/* deconstruct the name list */
|
||||||
|
DeconstructQualifiedName(names, &schemaname, &objname);
|
||||||
|
|
||||||
if (schemaname)
|
if (schemaname)
|
||||||
{
|
{
|
||||||
/* use exact schema given */
|
/* use exact schema given */
|
||||||
@ -1158,6 +1126,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
|
|||||||
if (!OidIsValid(namespaceId))
|
if (!OidIsValid(namespaceId))
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
elog(ERROR, "Namespace \"%s\" does not exist",
|
||||||
schemaname);
|
schemaname);
|
||||||
|
/* we do not check for USAGE rights here! */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.52 2002/07/20 05:16:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.53 2002/07/29 23:46:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,7 +22,6 @@
|
|||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_description.h"
|
#include "catalog/pg_description.h"
|
||||||
#include "catalog/pg_namespace.h"
|
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
#include "catalog/pg_rewrite.h"
|
#include "catalog/pg_rewrite.h"
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
@ -468,36 +467,28 @@ CommentNamespace(List *qualname, char *comment)
|
|||||||
{
|
{
|
||||||
Oid oid;
|
Oid oid;
|
||||||
Oid classoid;
|
Oid classoid;
|
||||||
HeapTuple tp;
|
|
||||||
char *namespace;
|
char *namespace;
|
||||||
|
|
||||||
if (length(qualname) != 1)
|
if (length(qualname) != 1)
|
||||||
elog(ERROR, "CommentSchema: schema name may not be qualified");
|
elog(ERROR, "CommentSchema: schema name may not be qualified");
|
||||||
namespace = strVal(lfirst(qualname));
|
namespace = strVal(lfirst(qualname));
|
||||||
|
|
||||||
tp = SearchSysCache(NAMESPACENAME,
|
oid = GetSysCacheOid(NAMESPACENAME,
|
||||||
CStringGetDatum(namespace),
|
CStringGetDatum(namespace),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tp))
|
if (!OidIsValid(oid))
|
||||||
elog(ERROR, "CommentSchema: Schema \"%s\" could not be found",
|
elog(ERROR, "CommentSchema: Schema \"%s\" could not be found",
|
||||||
namespace);
|
namespace);
|
||||||
|
|
||||||
/* no TupleDesc here to Assert(...->tdhasoid); */
|
|
||||||
oid = HeapTupleGetOid(tp);
|
|
||||||
|
|
||||||
/* Check object security */
|
/* Check object security */
|
||||||
if (!pg_namespace_ownercheck(oid, GetUserId()))
|
if (!pg_namespace_ownercheck(oid, GetUserId()))
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER, namespace);
|
aclcheck_error(ACLCHECK_NOT_OWNER, namespace);
|
||||||
|
|
||||||
/* pg_namespace doesn't have a hard-coded OID, so must look it up */
|
/* pg_namespace doesn't have a hard-coded OID, so must look it up */
|
||||||
classoid = get_relname_relid(NamespaceRelationName, PG_CATALOG_NAMESPACE);
|
classoid = get_system_catalog_relid(NamespaceRelationName);
|
||||||
Assert(OidIsValid(classoid));
|
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
CreateComments(oid, classoid, 0, comment);
|
CreateComments(oid, classoid, 0, comment);
|
||||||
|
|
||||||
/* Cleanup */
|
|
||||||
ReleaseSysCache(tp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -607,8 +598,7 @@ CommentRule(List *qualname, char *comment)
|
|||||||
aclcheck_error(aclcheck, rulename);
|
aclcheck_error(aclcheck, rulename);
|
||||||
|
|
||||||
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
|
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
|
||||||
classoid = get_relname_relid(RewriteRelationName, PG_CATALOG_NAMESPACE);
|
classoid = get_system_catalog_relid(RewriteRelationName);
|
||||||
Assert(OidIsValid(classoid));
|
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
|
|
||||||
@ -740,8 +730,7 @@ CommentOperator(List *opername, List *arguments, char *comment)
|
|||||||
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(opername));
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(opername));
|
||||||
|
|
||||||
/* pg_operator doesn't have a hard-coded OID, so must look it up */
|
/* pg_operator doesn't have a hard-coded OID, so must look it up */
|
||||||
classoid = get_relname_relid(OperatorRelationName, PG_CATALOG_NAMESPACE);
|
classoid = get_system_catalog_relid(OperatorRelationName);
|
||||||
Assert(OidIsValid(classoid));
|
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
CreateComments(oid, classoid, 0, comment);
|
CreateComments(oid, classoid, 0, comment);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.78 2002/07/20 05:16:57 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.79 2002/07/29 23:46:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -410,9 +410,8 @@ static Oid
|
|||||||
GetAttrOpClass(IndexElem *attribute, Oid attrType,
|
GetAttrOpClass(IndexElem *attribute, Oid attrType,
|
||||||
char *accessMethodName, Oid accessMethodId)
|
char *accessMethodName, Oid accessMethodId)
|
||||||
{
|
{
|
||||||
char *catalogname;
|
char *schemaname;
|
||||||
char *schemaname = NULL;
|
char *opcname;
|
||||||
char *opcname = NULL;
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Oid opClassId,
|
Oid opClassId,
|
||||||
opInputType;
|
opInputType;
|
||||||
@ -434,42 +433,14 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* deconstruct the name list */
|
/* deconstruct the name list */
|
||||||
switch (length(attribute->opclass))
|
DeconstructQualifiedName(attribute->opclass, &schemaname, &opcname);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
opcname = strVal(lfirst(attribute->opclass));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
schemaname = strVal(lfirst(attribute->opclass));
|
|
||||||
opcname = strVal(lsecond(attribute->opclass));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
catalogname = strVal(lfirst(attribute->opclass));
|
|
||||||
schemaname = strVal(lsecond(attribute->opclass));
|
|
||||||
opcname = strVal(lfirst(lnext(lnext(attribute->opclass))));
|
|
||||||
/*
|
|
||||||
* We check the catalog name and then ignore it.
|
|
||||||
*/
|
|
||||||
if (strcmp(catalogname, DatabaseName) != 0)
|
|
||||||
elog(ERROR, "Cross-database references are not implemented");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "Improper opclass name (too many dotted names): %s",
|
|
||||||
NameListToString(attribute->opclass));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (schemaname)
|
if (schemaname)
|
||||||
{
|
{
|
||||||
/* Look in specific schema only */
|
/* Look in specific schema only */
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
namespaceId = LookupExplicitNamespace(schemaname);
|
||||||
CStringGetDatum(schemaname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(namespaceId))
|
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
|
||||||
schemaname);
|
|
||||||
tuple = SearchSysCache(CLAAMNAMENSP,
|
tuple = SearchSysCache(CLAAMNAMENSP,
|
||||||
ObjectIdGetDatum(accessMethodId),
|
ObjectIdGetDatum(accessMethodId),
|
||||||
PointerGetDatum(opcname),
|
PointerGetDatum(opcname),
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.1 2002/07/29 22:14:10 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.2 2002/07/29 23:46:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -467,10 +467,9 @@ storeProcedures(Oid opclassoid, int numProcs, Oid *procedures)
|
|||||||
void
|
void
|
||||||
RemoveOpClass(RemoveOpClassStmt *stmt)
|
RemoveOpClass(RemoveOpClassStmt *stmt)
|
||||||
{
|
{
|
||||||
Oid amID, opcID;
|
Oid amID, opcID;
|
||||||
char *catalogname;
|
char *schemaname;
|
||||||
char *schemaname = NULL;
|
char *opcname;
|
||||||
char *opcname = NULL;
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
ObjectAddress object;
|
ObjectAddress object;
|
||||||
|
|
||||||
@ -489,42 +488,14 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* deconstruct the name list */
|
/* deconstruct the name list */
|
||||||
switch (length(stmt->opclassname))
|
DeconstructQualifiedName(stmt->opclassname, &schemaname, &opcname);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
opcname = strVal(lfirst(stmt->opclassname));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
schemaname = strVal(lfirst(stmt->opclassname));
|
|
||||||
opcname = strVal(lsecond(stmt->opclassname));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
catalogname = strVal(lfirst(stmt->opclassname));
|
|
||||||
schemaname = strVal(lsecond(stmt->opclassname));
|
|
||||||
opcname = strVal(lfirst(lnext(lnext(stmt->opclassname))));
|
|
||||||
/*
|
|
||||||
* We check the catalog name and then ignore it.
|
|
||||||
*/
|
|
||||||
if (strcmp(catalogname, DatabaseName) != 0)
|
|
||||||
elog(ERROR, "Cross-database references are not implemented");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "Improper opclass name (too many dotted names): %s",
|
|
||||||
NameListToString(stmt->opclassname));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (schemaname)
|
if (schemaname)
|
||||||
{
|
{
|
||||||
/* Look in specific schema only */
|
/* Look in specific schema only */
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
namespaceId = LookupExplicitNamespace(schemaname);
|
||||||
CStringGetDatum(schemaname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(namespaceId))
|
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
|
||||||
schemaname);
|
|
||||||
tuple = SearchSysCache(CLAAMNAMENSP,
|
tuple = SearchSysCache(CLAAMNAMENSP,
|
||||||
ObjectIdGetDatum(amID),
|
ObjectIdGetDatum(amID),
|
||||||
PointerGetDatum(opcname),
|
PointerGetDatum(opcname),
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.45 2002/07/20 05:16:58 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.46 2002/07/29 23:46:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -99,35 +99,11 @@ LookupTypeName(const TypeName *typename)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Normal reference to a type name */
|
/* Normal reference to a type name */
|
||||||
char *catalogname;
|
char *schemaname;
|
||||||
char *schemaname = NULL;
|
char *typname;
|
||||||
char *typname = NULL;
|
|
||||||
|
|
||||||
/* deconstruct the name list */
|
/* deconstruct the name list */
|
||||||
switch (length(typename->names))
|
DeconstructQualifiedName(typename->names, &schemaname, &typname);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
typname = strVal(lfirst(typename->names));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
schemaname = strVal(lfirst(typename->names));
|
|
||||||
typname = strVal(lsecond(typename->names));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
catalogname = strVal(lfirst(typename->names));
|
|
||||||
schemaname = strVal(lsecond(typename->names));
|
|
||||||
typname = strVal(lfirst(lnext(lnext(typename->names))));
|
|
||||||
/*
|
|
||||||
* We check the catalog name and then ignore it.
|
|
||||||
*/
|
|
||||||
if (strcmp(catalogname, DatabaseName) != 0)
|
|
||||||
elog(ERROR, "Cross-database references are not implemented");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "Improper type name (too many dotted names): %s",
|
|
||||||
NameListToString(typename->names));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If an array reference, look up the array type instead */
|
/* If an array reference, look up the array type instead */
|
||||||
if (typename->arrayBounds != NIL)
|
if (typename->arrayBounds != NIL)
|
||||||
@ -138,12 +114,7 @@ LookupTypeName(const TypeName *typename)
|
|||||||
/* Look in specific schema only */
|
/* Look in specific schema only */
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
namespaceId = LookupExplicitNamespace(schemaname);
|
||||||
CStringGetDatum(schemaname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(namespaceId))
|
|
||||||
elog(ERROR, "Namespace \"%s\" does not exist",
|
|
||||||
schemaname);
|
|
||||||
restype = GetSysCacheOid(TYPENAMENSP,
|
restype = GetSysCacheOid(TYPENAMENSP,
|
||||||
PointerGetDatum(typname),
|
PointerGetDatum(typname),
|
||||||
ObjectIdGetDatum(namespaceId),
|
ObjectIdGetDatum(namespaceId),
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: namespace.h,v 1.16 2002/07/16 06:58:13 ishii Exp $
|
* $Id: namespace.h,v 1.17 2002/07/29 23:46:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -66,6 +66,11 @@ extern OpclassCandidateList OpclassGetCandidates(Oid amid);
|
|||||||
extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname);
|
extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname);
|
||||||
extern bool OpclassIsVisible(Oid opcid);
|
extern bool OpclassIsVisible(Oid opcid);
|
||||||
|
|
||||||
|
extern void DeconstructQualifiedName(List *names,
|
||||||
|
char **nspname_p,
|
||||||
|
char **objname_p);
|
||||||
|
extern Oid LookupExplicitNamespace(char *nspname);
|
||||||
|
|
||||||
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
|
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
|
||||||
extern RangeVar *makeRangeVarFromNameList(List *names);
|
extern RangeVar *makeRangeVarFromNameList(List *names);
|
||||||
extern char *NameListToString(List *names);
|
extern char *NameListToString(List *names);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user