Refactor typenameTypeId()

Split the old typenameTypeId() into two functions: A new typenameTypeId() that
returns only a type OID, and typenameTypeIdAndMod() that returns type OID and
typmod.  This isolates call sites better that actually care about the typmod.
This commit is contained in:
Peter Eisentraut 2010-10-25 21:40:46 +03:00
parent c6873eac4c
commit 35670340f5
16 changed files with 70 additions and 52 deletions

View File

@ -536,7 +536,7 @@ BuildDescForRelation(List *schema)
attnum++; attnum++;
attname = entry->colname; attname = entry->colname;
atttypid = typenameTypeId(NULL, entry->typeName, &atttypmod); typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
attdim = list_length(entry->typeName->arrayBounds); attdim = list_length(entry->typeName->arrayBounds);
if (entry->typeName->setof) if (entry->typeName->setof)

View File

@ -137,7 +137,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
case OBJECT_TYPE: case OBJECT_TYPE:
address.classId = TypeRelationId; address.classId = TypeRelationId;
address.objectId = address.objectId =
typenameTypeId(NULL, makeTypeNameFromNameList(objname), NULL); typenameTypeId(NULL, makeTypeNameFromNameList(objname));
address.objectSubId = 0; address.objectSubId = 0;
break; break;
case OBJECT_AGGREGATE: case OBJECT_AGGREGATE:
@ -184,8 +184,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
{ {
TypeName *sourcetype = (TypeName *) linitial(objname); TypeName *sourcetype = (TypeName *) linitial(objname);
TypeName *targettype = (TypeName *) linitial(objargs); TypeName *targettype = (TypeName *) linitial(objargs);
Oid sourcetypeid = typenameTypeId(NULL, sourcetype, NULL); Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
Oid targettypeid = typenameTypeId(NULL, targettype, NULL); Oid targettypeid = typenameTypeId(NULL, targettype);
address.classId = CastRelationId; address.classId = CastRelationId;
address.objectId = address.objectId =

View File

@ -142,7 +142,7 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
{ {
numArgs = 1; numArgs = 1;
aggArgTypes = (Oid *) palloc(sizeof(Oid)); aggArgTypes = (Oid *) palloc(sizeof(Oid));
aggArgTypes[0] = typenameTypeId(NULL, baseType, NULL); aggArgTypes[0] = typenameTypeId(NULL, baseType);
} }
} }
else else
@ -164,7 +164,7 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
{ {
TypeName *curTypeName = (TypeName *) lfirst(lc); TypeName *curTypeName = (TypeName *) lfirst(lc);
aggArgTypes[i++] = typenameTypeId(NULL, curTypeName, NULL); aggArgTypes[i++] = typenameTypeId(NULL, curTypeName);
} }
} }
@ -179,7 +179,7 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
* worse) by connecting up incompatible internal-using functions in an * worse) by connecting up incompatible internal-using functions in an
* aggregate. * aggregate.
*/ */
transTypeId = typenameTypeId(NULL, transType, NULL); transTypeId = typenameTypeId(NULL, transType);
if (get_typtype(transTypeId) == TYPTYPE_PSEUDO && if (get_typtype(transTypeId) == TYPTYPE_PSEUDO &&
!IsPolymorphicType(transTypeId)) !IsPolymorphicType(transTypeId))
{ {

View File

@ -607,8 +607,8 @@ CheckCastComment(List *qualname, List *arguments)
targettype = (TypeName *) linitial(arguments); targettype = (TypeName *) linitial(arguments);
Assert(IsA(targettype, TypeName)); Assert(IsA(targettype, TypeName));
sourcetypeid = typenameTypeId(NULL, sourcetype, NULL); sourcetypeid = typenameTypeId(NULL, sourcetype);
targettypeid = typenameTypeId(NULL, targettype, NULL); targettypeid = typenameTypeId(NULL, targettype);
/* Permission check */ /* Permission check */
if (!pg_type_ownercheck(sourcetypeid, GetUserId()) if (!pg_type_ownercheck(sourcetypeid, GetUserId())

View File

@ -1496,8 +1496,8 @@ CreateCast(CreateCastStmt *stmt)
ObjectAddress myself, ObjectAddress myself,
referenced; referenced;
sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL); sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
targettypeid = typenameTypeId(NULL, stmt->targettype, NULL); targettypeid = typenameTypeId(NULL, stmt->targettype);
sourcetyptype = get_typtype(sourcetypeid); sourcetyptype = get_typtype(sourcetypeid);
targettyptype = get_typtype(targettypeid); targettyptype = get_typtype(targettypeid);
@ -1779,8 +1779,8 @@ DropCast(DropCastStmt *stmt)
ObjectAddress object; ObjectAddress object;
/* when dropping a cast, the types must exist even if you use IF EXISTS */ /* when dropping a cast, the types must exist even if you use IF EXISTS */
sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL); sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
targettypeid = typenameTypeId(NULL, stmt->targettype, NULL); targettypeid = typenameTypeId(NULL, stmt->targettype);
object.classId = CastRelationId; object.classId = CastRelationId;
object.objectId = get_cast_oid(sourcetypeid, targettypeid, object.objectId = get_cast_oid(sourcetypeid, targettypeid,

View File

@ -398,7 +398,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
errmsg("must be superuser to create an operator class"))); errmsg("must be superuser to create an operator class")));
/* Look up the datatype */ /* Look up the datatype */
typeoid = typenameTypeId(NULL, stmt->datatype, NULL); typeoid = typenameTypeId(NULL, stmt->datatype);
#ifdef NOT_USED #ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */ /* XXX this is unnecessary given the superuser check above */
@ -540,7 +540,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("storage type specified more than once"))); errmsg("storage type specified more than once")));
storageoid = typenameTypeId(NULL, item->storedtype, NULL); storageoid = typenameTypeId(NULL, item->storedtype);
#ifdef NOT_USED #ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */ /* XXX this is unnecessary given the superuser check above */
@ -1009,12 +1009,12 @@ processTypesSpec(List *args, Oid *lefttype, Oid *righttype)
Assert(args != NIL); Assert(args != NIL);
typeName = (TypeName *) linitial(args); typeName = (TypeName *) linitial(args);
*lefttype = typenameTypeId(NULL, typeName, NULL); *lefttype = typenameTypeId(NULL, typeName);
if (list_length(args) > 1) if (list_length(args) > 1)
{ {
typeName = (TypeName *) lsecond(args); typeName = (TypeName *) lsecond(args);
*righttype = typenameTypeId(NULL, typeName, NULL); *righttype = typenameTypeId(NULL, typeName);
} }
else else
*righttype = *lefttype; *righttype = *lefttype;

View File

@ -167,9 +167,9 @@ DefineOperator(List *names, List *parameters)
/* Transform type names to type OIDs */ /* Transform type names to type OIDs */
if (typeName1) if (typeName1)
typeId1 = typenameTypeId(NULL, typeName1, NULL); typeId1 = typenameTypeId(NULL, typeName1);
if (typeName2) if (typeName2)
typeId2 = typenameTypeId(NULL, typeName2, NULL); typeId2 = typenameTypeId(NULL, typeName2);
if (!OidIsValid(typeId1) && !OidIsValid(typeId2)) if (!OidIsValid(typeId1) && !OidIsValid(typeId2))
ereport(ERROR, ereport(ERROR,

View File

@ -90,7 +90,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
foreach(l, stmt->argtypes) foreach(l, stmt->argtypes)
{ {
TypeName *tn = lfirst(l); TypeName *tn = lfirst(l);
Oid toid = typenameTypeId(pstate, tn, NULL); Oid toid = typenameTypeId(pstate, tn);
argtypes[i++] = toid; argtypes[i++] = toid;
} }

View File

@ -464,7 +464,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
(void) heap_reloptions(relkind, reloptions, true); (void) heap_reloptions(relkind, reloptions, true);
if (stmt->ofTypename) if (stmt->ofTypename)
ofTypeId = typenameTypeId(NULL, stmt->ofTypename, NULL); ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
else else
ofTypeId = InvalidOid; ofTypeId = InvalidOid;
@ -1399,7 +1399,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
(errmsg("merging multiple inherited definitions of column \"%s\"", (errmsg("merging multiple inherited definitions of column \"%s\"",
attributeName))); attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1); def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
defTypeId = typenameTypeId(NULL, def->typeName, &deftypmod); typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
if (defTypeId != attribute->atttypid || if (defTypeId != attribute->atttypid ||
deftypmod != attribute->atttypmod) deftypmod != attribute->atttypmod)
ereport(ERROR, ereport(ERROR,
@ -1571,8 +1571,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
(errmsg("merging column \"%s\" with inherited definition", (errmsg("merging column \"%s\" with inherited definition",
attributeName))); attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1); def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
defTypeId = typenameTypeId(NULL, def->typeName, &deftypmod); typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
newTypeId = typenameTypeId(NULL, newdef->typeName, &newtypmod); typenameTypeIdAndMod(NULL, newdef->typeName, &newTypeId, &newtypmod);
if (defTypeId != newTypeId || deftypmod != newtypmod) if (defTypeId != newTypeId || deftypmod != newtypmod)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
@ -3910,7 +3910,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
int32 ctypmod; int32 ctypmod;
/* Child column must match by type */ /* Child column must match by type */
ctypeId = typenameTypeId(NULL, colDef->typeName, &ctypmod); typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
if (ctypeId != childatt->atttypid || if (ctypeId != childatt->atttypid ||
ctypmod != childatt->atttypmod) ctypmod != childatt->atttypmod)
ereport(ERROR, ereport(ERROR,
@ -6100,7 +6100,7 @@ ATPrepAlterColumnType(List **wqueue,
colName))); colName)));
/* Look up the target type */ /* Look up the target type */
targettype = typenameTypeId(NULL, typeName, &targettypmod); typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
/* make sure datatype is legal for a column */ /* make sure datatype is legal for a column */
CheckAttributeType(colName, targettype, false); CheckAttributeType(colName, targettype, false);

View File

@ -333,7 +333,7 @@ DefineType(List *names, List *parameters)
} }
if (elemTypeEl) if (elemTypeEl)
{ {
elemType = typenameTypeId(NULL, defGetTypeName(elemTypeEl), NULL); elemType = typenameTypeId(NULL, defGetTypeName(elemTypeEl));
/* disallow arrays of pseudotypes */ /* disallow arrays of pseudotypes */
if (get_typtype(elemType) == TYPTYPE_PSEUDO) if (get_typtype(elemType) == TYPTYPE_PSEUDO)
ereport(ERROR, ereport(ERROR,
@ -1205,7 +1205,7 @@ AlterEnum(AlterEnumStmt *stmt)
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(stmt->typeName); typename = makeTypeNameFromNameList(stmt->typeName);
enum_type_oid = typenameTypeId(NULL, typename, NULL); enum_type_oid = typenameTypeId(NULL, typename);
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(enum_type_oid)); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(enum_type_oid));
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
@ -1620,7 +1620,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
domainoid = typenameTypeId(NULL, typename, NULL); domainoid = typenameTypeId(NULL, typename);
/* Look up the domain in the type table */ /* Look up the domain in the type table */
rel = heap_open(TypeRelationId, RowExclusiveLock); rel = heap_open(TypeRelationId, RowExclusiveLock);
@ -1746,7 +1746,7 @@ AlterDomainNotNull(List *names, bool notNull)
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
domainoid = typenameTypeId(NULL, typename, NULL); domainoid = typenameTypeId(NULL, typename);
/* Look up the domain in the type table */ /* Look up the domain in the type table */
typrel = heap_open(TypeRelationId, RowExclusiveLock); typrel = heap_open(TypeRelationId, RowExclusiveLock);
@ -1846,7 +1846,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
domainoid = typenameTypeId(NULL, typename, NULL); domainoid = typenameTypeId(NULL, typename);
/* Look up the domain in the type table */ /* Look up the domain in the type table */
rel = heap_open(TypeRelationId, RowExclusiveLock); rel = heap_open(TypeRelationId, RowExclusiveLock);
@ -1919,7 +1919,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
domainoid = typenameTypeId(NULL, typename, NULL); domainoid = typenameTypeId(NULL, typename);
/* Look up the domain in the type table */ /* Look up the domain in the type table */
typrel = heap_open(TypeRelationId, RowExclusiveLock); typrel = heap_open(TypeRelationId, RowExclusiveLock);
@ -2540,7 +2540,7 @@ RenameType(List *names, const char *newTypeName)
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
typeOid = typenameTypeId(NULL, typename, NULL); typeOid = typenameTypeId(NULL, typename);
/* Look up the type in the type table */ /* Look up the type in the type table */
rel = heap_open(TypeRelationId, RowExclusiveLock); rel = heap_open(TypeRelationId, RowExclusiveLock);
@ -2769,7 +2769,7 @@ AlterTypeNamespace(List *names, const char *newschema)
/* Make a TypeName so we can use standard type lookup machinery */ /* Make a TypeName so we can use standard type lookup machinery */
typename = makeTypeNameFromNameList(names); typename = makeTypeNameFromNameList(names);
typeOid = typenameTypeId(NULL, typename, NULL); typeOid = typenameTypeId(NULL, typename);
/* check permissions on type */ /* check permissions on type */
if (!pg_type_ownercheck(typeOid, GetUserId())) if (!pg_type_ownercheck(typeOid, GetUserId()))

View File

@ -159,8 +159,8 @@ transformExpr(ParseState *pstate, Node *expr)
Oid elementType; Oid elementType;
int32 targetTypmod; int32 targetTypmod;
targetType = typenameTypeId(pstate, tc->typeName, typenameTypeIdAndMod(pstate, tc->typeName,
&targetTypmod); &targetType, &targetTypmod);
/* /*
* If target is a domain over array, work with the base * If target is a domain over array, work with the base
* array type here. transformTypeCast below will cast the * array type here. transformTypeCast below will cast the
@ -1031,7 +1031,7 @@ transformAExprOf(ParseState *pstate, A_Expr *a)
ltype = exprType(lexpr); ltype = exprType(lexpr);
foreach(telem, (List *) a->rexpr) foreach(telem, (List *) a->rexpr)
{ {
rtype = typenameTypeId(pstate, lfirst(telem), NULL); rtype = typenameTypeId(pstate, lfirst(telem));
matched = (rtype == ltype); matched = (rtype == ltype);
if (matched) if (matched)
break; break;
@ -1889,7 +1889,7 @@ transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
XMLOID, XMLOID,
"XMLSERIALIZE")); "XMLSERIALIZE"));
targetType = typenameTypeId(pstate, xs->typeName, &targetTypmod); typenameTypeIdAndMod(pstate, xs->typeName, &targetType, &targetTypmod);
xexpr->xmloption = xs->xmloption; xexpr->xmloption = xs->xmloption;
xexpr->location = xs->location; xexpr->location = xs->location;
@ -2052,7 +2052,7 @@ transformTypeCast(ParseState *pstate, TypeCast *tc)
int32 targetTypmod; int32 targetTypmod;
int location; int location;
targetType = typenameTypeId(pstate, tc->typeName, &targetTypmod); typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
if (inputType == InvalidOid) if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */ return expr; /* do nothing if NULL input */

View File

@ -148,12 +148,12 @@ LookupOperNameTypeNames(ParseState *pstate, List *opername,
if (oprleft == NULL) if (oprleft == NULL)
leftoid = InvalidOid; leftoid = InvalidOid;
else else
leftoid = typenameTypeId(pstate, oprleft, NULL); leftoid = typenameTypeId(pstate, oprleft);
if (oprright == NULL) if (oprright == NULL)
rightoid = InvalidOid; rightoid = InvalidOid;
else else
rightoid = typenameTypeId(pstate, oprright, NULL); rightoid = typenameTypeId(pstate, oprright);
return LookupOperName(pstate, opername, leftoid, rightoid, return LookupOperName(pstate, opername, leftoid, rightoid,
noError, location); noError, location);

View File

@ -1165,7 +1165,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
errmsg("column \"%s\" cannot be declared SETOF", errmsg("column \"%s\" cannot be declared SETOF",
attrname), attrname),
parser_errposition(pstate, n->typeName->location))); parser_errposition(pstate, n->typeName->location)));
attrtype = typenameTypeId(pstate, n->typeName, &attrtypmod); typenameTypeIdAndMod(pstate, n->typeName, &attrtype, &attrtypmod);
eref->colnames = lappend(eref->colnames, makeString(attrname)); eref->colnames = lappend(eref->colnames, makeString(attrname));
rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype); rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype);
rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod); rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod);

View File

@ -206,24 +206,41 @@ typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
} }
/* /*
* typenameTypeId - given a TypeName, return the type's OID and typmod * typenameTypeId - given a TypeName, return the type's OID
* *
* This is equivalent to typenameType, but we only hand back the type OID * This is similar to typenameType, but we only hand back the type OID
* not the syscache entry. * not the syscache entry.
*/ */
Oid Oid
typenameTypeId(ParseState *pstate, const TypeName *typeName, int32 *typmod_p) typenameTypeId(ParseState *pstate, const TypeName *typeName)
{ {
Oid typoid; Oid typoid;
Type tup; Type tup;
tup = typenameType(pstate, typeName, typmod_p); tup = typenameType(pstate, typeName, NULL);
typoid = HeapTupleGetOid(tup); typoid = HeapTupleGetOid(tup);
ReleaseSysCache(tup); ReleaseSysCache(tup);
return typoid; return typoid;
} }
/*
* typenameTypeIdAndMod - given a TypeName, return the type's OID and typmod
*
* This is equivalent to typenameType, but we only hand back the type OID
* and typmod, not the syscache entry.
*/
void
typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
Oid *typeid_p, int32 *typmod_p)
{
Type tup;
tup = typenameType(pstate, typeName, typmod_p);
*typeid_p = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
}
/* /*
* typenameTypeMod - given a TypeName, return the internal typmod value * typenameTypeMod - given a TypeName, return the internal typmod value
* *
@ -561,7 +578,7 @@ pts_error_callback(void *arg)
* the string and convert it to a type OID and type modifier. * the string and convert it to a type OID and type modifier.
*/ */
void void
parseTypeString(const char *str, Oid *type_id, int32 *typmod_p) parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p)
{ {
StringInfoData buf; StringInfoData buf;
List *raw_parsetree_list; List *raw_parsetree_list;
@ -635,7 +652,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod_p)
if (typeName->setof) if (typeName->setof)
goto fail; goto fail;
*type_id = typenameTypeId(NULL, typeName, typmod_p); typenameTypeIdAndMod(NULL, typeName, typeid_p, typmod_p);
pfree(buf.data); pfree(buf.data);

View File

@ -5621,7 +5621,7 @@ flatten_set_variable_args(const char *name, List *args)
Datum interval; Datum interval;
char *intervalout; char *intervalout;
typoid = typenameTypeId(NULL, typeName, &typmod); typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
Assert(typoid == INTERVALOID); Assert(typoid == INTERVALOID);
interval = interval =

View File

@ -23,8 +23,9 @@ extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName,
int32 *typmod_p); int32 *typmod_p);
extern Type typenameType(ParseState *pstate, const TypeName *typeName, extern Type typenameType(ParseState *pstate, const TypeName *typeName,
int32 *typmod_p); int32 *typmod_p);
extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName, extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName);
int32 *typmod_p); extern void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
Oid *typeid_p, int32 *typmod_p);
extern char *TypeNameToString(const TypeName *typeName); extern char *TypeNameToString(const TypeName *typeName);
extern char *TypeNameListToString(List *typenames); extern char *TypeNameListToString(List *typenames);
@ -40,7 +41,7 @@ extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
extern Oid typeidTypeRelid(Oid type_id); extern Oid typeidTypeRelid(Oid type_id);
extern void parseTypeString(const char *str, Oid *type_id, int32 *typmod_p); extern void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p);
#define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid) #define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid)