Replace hardcoded switch in object_exists() with a lookup table.

There's no particular advantage to this change on its face; indeed,
it's possible that this might be slightly slower than the old way.
But it makes this information more easily accessible to other
functions, and therefore paves the way for future code consolidation.
Performance isn't critical here, so there's no need to be smart about
how we do the search.

This is a heavily cut-down version of a patch from KaiGai Kohei,
with several fixes by me.  Additional review from Dimitri Fontaine.
This commit is contained in:
Robert Haas 2011-10-11 09:14:30 -04:00
parent e76bcaba9c
commit fa351d5a0d
1 changed files with 166 additions and 91 deletions

View File

@ -82,6 +82,147 @@ static ObjectAddress get_object_address_opcf(ObjectType objtype, List *objname,
List *objargs, bool missing_ok);
static bool object_exists(ObjectAddress address);
/*
* ObjectProperty
*
* This array provides a common part of system object structure; to help
* consolidate routines to handle various kind of object classes.
*/
typedef struct
{
Oid class_oid; /* oid of catalog */
Oid oid_index_oid; /* oid of index on system oid column */
int oid_catcache_id; /* id of catcache on system oid column */
} ObjectPropertyType;
static ObjectPropertyType ObjectProperty[] =
{
{
CastRelationId,
CastOidIndexId,
-1
},
{
CollationRelationId,
CollationOidIndexId,
COLLOID
},
{
ConstraintRelationId,
ConstraintOidIndexId,
CONSTROID
},
{
ConversionRelationId,
ConversionOidIndexId,
CONVOID
},
{
DatabaseRelationId,
DatabaseOidIndexId,
DATABASEOID
},
{
ExtensionRelationId,
ExtensionOidIndexId,
-1
},
{
ForeignDataWrapperRelationId,
ForeignDataWrapperOidIndexId,
FOREIGNDATAWRAPPEROID
},
{
ForeignServerRelationId,
ForeignServerOidIndexId,
FOREIGNSERVEROID
},
{
ProcedureRelationId,
ProcedureOidIndexId,
PROCOID
},
{
LanguageRelationId,
LanguageOidIndexId,
LANGOID
},
{
LargeObjectMetadataRelationId,
LargeObjectMetadataOidIndexId,
-1
},
{
OperatorClassRelationId,
OpclassOidIndexId,
CLAOID
},
{
OperatorRelationId,
OperatorOidIndexId,
OPEROID
},
{
OperatorFamilyRelationId,
OpfamilyOidIndexId,
OPFAMILYOID
},
{
AuthIdRelationId,
AuthIdOidIndexId,
AUTHOID
},
{
RewriteRelationId,
RewriteOidIndexId,
-1
},
{
NamespaceRelationId,
NamespaceOidIndexId,
NAMESPACEOID
},
{
RelationRelationId,
ClassOidIndexId,
RELOID
},
{
TableSpaceRelationId,
TablespaceOidIndexId,
TABLESPACEOID,
},
{
TriggerRelationId,
TriggerOidIndexId,
-1
},
{
TSConfigRelationId,
TSConfigOidIndexId,
TSCONFIGOID
},
{
TSDictionaryRelationId,
TSDictionaryOidIndexId,
TSDICTOID
},
{
TSParserRelationId,
TSParserOidIndexId,
TSPARSEROID
},
{
TSTemplateRelationId,
TSTemplateOidIndexId,
TSTEMPLATEOID
},
{
TypeRelationId,
TypeOidIndexId,
TYPEOID
}
};
/*
* Translate an object name and arguments (as passed by the parser) to an
@ -448,7 +589,7 @@ get_relation_by_qualified_name(ObjectType objtype, List *objname,
break;
}
/* Done */
/* Done. */
address.objectId = RelationGetRelid(relation);
*relp = relation;
@ -697,99 +838,33 @@ object_exists(ObjectAddress address)
}
return found;
}
/*
* For object types that have a relevant syscache, we use it; for
* everything else, we'll have to do an index-scan. This switch sets
* either the cache to be used for the syscache lookup, or the index to be
* used for the index scan.
*/
switch (address.classId)
else
{
case RelationRelationId:
cache = RELOID;
break;
case RewriteRelationId:
indexoid = RewriteOidIndexId;
break;
case TriggerRelationId:
indexoid = TriggerOidIndexId;
break;
case ConstraintRelationId:
cache = CONSTROID;
break;
case DatabaseRelationId:
cache = DATABASEOID;
break;
case TableSpaceRelationId:
cache = TABLESPACEOID;
break;
case AuthIdRelationId:
cache = AUTHOID;
break;
case NamespaceRelationId:
cache = NAMESPACEOID;
break;
case LanguageRelationId:
cache = LANGOID;
break;
case TypeRelationId:
cache = TYPEOID;
break;
case ProcedureRelationId:
cache = PROCOID;
break;
case OperatorRelationId:
cache = OPEROID;
break;
case CollationRelationId:
cache = COLLOID;
break;
case ConversionRelationId:
cache = CONVOID;
break;
case OperatorClassRelationId:
cache = CLAOID;
break;
case OperatorFamilyRelationId:
cache = OPFAMILYOID;
break;
case LargeObjectRelationId:
int index;
/*
* Weird backward compatibility hack: ObjectAddress notation uses
* LargeObjectRelationId for large objects, but since PostgreSQL
* 9.0, the relevant catalog is actually
* LargeObjectMetadataRelationId.
*/
/*
* Weird backward compatibility hack: ObjectAddress notation uses
* LargeObjectRelationId for large objects, but since PostgreSQL
* 9.0, the relevant catalog is actually LargeObjectMetadataRelationId.
*/
if (address.classId == LargeObjectRelationId)
address.classId = LargeObjectMetadataRelationId;
indexoid = LargeObjectMetadataOidIndexId;
break;
case CastRelationId:
indexoid = CastOidIndexId;
break;
case ForeignDataWrapperRelationId:
cache = FOREIGNDATAWRAPPEROID;
break;
case ForeignServerRelationId:
cache = FOREIGNSERVEROID;
break;
case TSParserRelationId:
cache = TSPARSEROID;
break;
case TSDictionaryRelationId:
cache = TSDICTOID;
break;
case TSTemplateRelationId:
cache = TSTEMPLATEOID;
break;
case TSConfigRelationId:
cache = TSCONFIGOID;
break;
case ExtensionRelationId:
indexoid = ExtensionOidIndexId;
break;
default:
/*
* For object types that have a relevant syscache, we use it; for
* everything else, we'll have to do an index-scan. Search the
* ObjectProperty array to find out which it is.
*/
for (index = 0; index < lengthof(ObjectProperty); index++)
{
if (ObjectProperty[index].class_oid == address.classId)
{
cache = ObjectProperty[index].oid_catcache_id;
indexoid = ObjectProperty[index].oid_index_oid;
break;
}
}
if (index == lengthof(ObjectProperty))
elog(ERROR, "unrecognized classid: %u", address.classId);
}