static void setupUDT(Function self, ParseResult info, Form_pg_proc procStruct) { Oid udtId = 0; HeapTuple typeTup; Form_pg_type pgType; if(strcasecmp("input", info->methodName) == 0) { self->func.udt.udtFunction = UDT_input; udtId = procStruct->prorettype; } else if(strcasecmp("output", info->methodName) == 0) { self->func.udt.udtFunction = UDT_output; udtId = PARAM_OIDS(procStruct)[0]; } else if(strcasecmp("receive", info->methodName) == 0) { self->func.udt.udtFunction = UDT_receive; udtId = procStruct->prorettype; } else if(strcasecmp("send", info->methodName) == 0) { self->func.udt.udtFunction = UDT_send; udtId = PARAM_OIDS(procStruct)[0]; } else { ereport(ERROR, ( errcode(ERRCODE_SYNTAX_ERROR), errmsg("Unknown UDT function %s", info->methodName))); } typeTup = PgObject_getValidTuple(TYPEOID, udtId, "type"); pgType = (Form_pg_type)GETSTRUCT(typeTup); self->func.udt.udt = UDT_registerUDT(self->clazz, udtId, pgType, 0, true); ReleaseSysCache(typeTup); }
Type Type_fromOid(Oid typeId, jobject typeMap) { CacheEntry ce; HeapTuple typeTup; Form_pg_type typeStruct; Type type = Type_fromOidCache(typeId); if(type != 0) return type; typeTup = PgObject_getValidTuple(TYPEOID, typeId, "type"); typeStruct = (Form_pg_type)GETSTRUCT(typeTup); if(typeStruct->typelem != 0 && typeStruct->typlen == -1) { type = Type_getArrayType(Type_fromOid(typeStruct->typelem, typeMap), typeId); goto finally; } /* For some reason, the anyarray is *not* an array with anyelement as the * element type. We'd like to see it that way though. */ if(typeId == ANYARRAYOID) { type = Type_getArrayType(Type_fromOid(ANYELEMENTOID, typeMap), typeId); goto finally; } if(typeStruct->typbasetype != 0) { /* Domain type, recurse using the base type (which in turn may * also be a domain) */ type = Type_fromOid(typeStruct->typbasetype, typeMap); goto finally; } if(typeMap != 0) { jobject joid = Oid_create(typeId); jclass typeClass = (jclass)JNI_callObjectMethod(typeMap, s_Map_get, joid); JNI_deleteLocalRef(joid); if(typeClass != 0) { TupleDesc tupleDesc = lookup_rowtype_tupdesc_noerror(typeId, -1, true); type = (Type)UDT_registerUDT(typeClass, typeId, typeStruct, tupleDesc, false); JNI_deleteLocalRef(typeClass); goto finally; } } /* Composite and record types will not have a TypeObtainer registered */ if(typeStruct->typtype == 'c' || (typeStruct->typtype == 'p' && typeId == RECORDOID)) { type = Composite_obtain(typeId); goto finally; } ce = (CacheEntry)HashMap_getByOid(s_obtainerByOid, typeId); if(ce == 0) /* * Default to String and standard textin/textout coersion. */ type = String_obtain(typeId); else { type = ce->type; if(type == 0) type = ce->obtainer(typeId); } finally: ReleaseSysCache(typeTup); Type_cacheByOid(typeId, type); return type; }