Beispiel #1
0
Type Type_getCoerceIn(Type self, Type other)
{
	Oid  funcId;
	Type coerce;
	Oid  fromOid = other->typeId;
	Oid  toOid = self->typeId;

	if(self->inCoercions != 0)
	{
		coerce = HashMap_getByOid(self->inCoercions, fromOid);
		if(coerce != 0)
			return coerce;
	}

	if (!find_coercion_pathway(toOid, fromOid, COERCION_EXPLICIT, &funcId))
	{
		elog(ERROR, "no conversion function from %s to %s",
			 format_type_be(fromOid),
			 format_type_be(toOid));
	}

	if(funcId == InvalidOid)
		/*
		 * Binary compatible type. No need for a special coercer
		 */
		return self;

	if(self->inCoercions == 0)
		self->inCoercions = HashMap_create(7, GetMemoryChunkContext(self));

	coerce = Coerce_createIn(self, other, funcId);
	HashMap_putByOid(self->inCoercions, fromOid, coerce);
	return coerce;
}
Beispiel #2
0
Function Function_getFunction(PG_FUNCTION_ARGS)
{
	Oid funcOid = fcinfo->flinfo->fn_oid;
	Function func = (Function)HashMap_getByOid(s_funcMap, funcOid);
	if(func == 0)
	{
		func = Function_create(fcinfo);
		HashMap_putByOid(s_funcMap, funcOid, func);
	}
	return func;
}
Beispiel #3
0
/*
 * Register this type.
 */
static void _registerType(Oid typeId, const char* javaTypeName, Type type, TypeObtainer obtainer)
{
	CacheEntry ce = (CacheEntry)MemoryContextAlloc(TopMemoryContext, sizeof(CacheEntryData));
	ce->typeId   = typeId;
	ce->type     = type;
	ce->obtainer = obtainer;

	if(javaTypeName != 0)
		HashMap_putByString(s_obtainerByJavaName, javaTypeName, ce);

	if(typeId != InvalidOid && HashMap_getByOid(s_obtainerByOid, typeId) == 0)
		HashMap_putByOid(s_obtainerByOid, typeId, ce);
}
Beispiel #4
0
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;
}
Beispiel #5
0
Type Type_fromOidCache(Oid typeId)
{
	return (Type)HashMap_getByOid(s_typeByOid, typeId);
}