Esempio n. 1
0
Type Array_fromOid2(Oid typeId, Type elementType, DatumCoercer coerceDatum, ObjectCoercer coerceObject)
{
	Type self;
	TypeClass arrayClass;
	const char* elemClassName    = PgObjectClass_getName(PgObject_getClass((PgObject)elementType));
	const char* elemJNISignature = Type_getJNISignature(elementType);
	const char* elemJavaTypeName = Type_getJavaTypeName(elementType);

	MemoryContext currCtx = MemoryContextSwitchTo(TopMemoryContext);

	char* tmp = palloc(strlen(elemClassName) + 3);
	sprintf(tmp, "%s[]", elemClassName);
	arrayClass = TypeClass_alloc(tmp);

	tmp = palloc(strlen(elemJNISignature) + 2);
	sprintf(tmp, "[%s", elemJNISignature);
	arrayClass->JNISignature = tmp;

	tmp = palloc(strlen(elemJavaTypeName) + 3);
	sprintf(tmp, "%s[]", elemJavaTypeName);
	arrayClass->javaTypeName = tmp;
	arrayClass->coerceDatum  = coerceDatum;
	arrayClass->coerceObject = coerceObject;
	arrayClass->canReplaceType = _Array_canReplaceType;
	self = TypeClass_allocInstance(arrayClass, typeId);
	MemoryContextSwitchTo(currCtx);

	self->elementType = elementType;
	Type_registerType(arrayClass->javaTypeName, self);

	if(Type_isPrimitive(elementType))
		self->objectType = Array_fromOid(typeId, Type_getObjectType(elementType));
	return self;
}
Esempio n. 2
0
static void Function_init(Function self, ParseResult info, Form_pg_proc procStruct, PG_FUNCTION_ARGS)
{
	StringInfoData sign;
	jobject loader;
	jstring className;

	/* Get the ClassLoader for the schema that this function belongs to
	 */
	jstring schemaName = getSchemaName(procStruct->pronamespace);

	/* Install the type map for the current schema. This must be done ASAP since
	 * many other functions (including obtaining the loader) depends on it.
	 */
	jobject tmp = JNI_callStaticObjectMethod(s_Loader_class, s_Loader_getTypeMap, schemaName);
	self->func.nonudt.typeMap = JNI_newGlobalRef(tmp);
	JNI_deleteLocalRef(tmp);

	self->readOnly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
	self->isUDT = info->isUDT;

	currentInvocation->function = self;

	/* Get the ClassLoader for the schema that this function belongs to
	 */
	loader = JNI_callStaticObjectMethod(s_Loader_class, s_Loader_getSchemaLoader, schemaName);
	JNI_deleteLocalRef(schemaName);

	elog(DEBUG1, "Loading class %s", info->className);
	className = String_createJavaStringFromNTS(info->className);

	tmp = JNI_callObjectMethod(loader, s_ClassLoader_loadClass, className);
	JNI_deleteLocalRef(loader);
	JNI_deleteLocalRef(className);

	self->clazz = (jclass)JNI_newGlobalRef(tmp);
	JNI_deleteLocalRef(tmp);

	if(self->isUDT)
	{
		setupUDT(self, info, procStruct);
		return;
	}

	if(CALLED_AS_TRIGGER(fcinfo))
	{
		self->func.nonudt.typeMap = 0;
		setupTriggerParams(self, info);
	}
	else
	{
		setupFunctionParams(self, info, procStruct, fcinfo);
	}


	initStringInfo(&sign);
	buildSignature(self, &sign, self->func.nonudt.returnType, false);

	elog(DEBUG1, "Obtaining method %s.%s %s", info->className, info->methodName, sign.data);
	self->func.nonudt.method = JNI_getStaticMethodIDOrNull(self->clazz, info->methodName, sign.data);

	if(self->func.nonudt.method == 0)
	{
		char* origSign = sign.data;
		Type altType = 0;
		Type realRetType = self->func.nonudt.returnType;

		elog(DEBUG1, "Method %s.%s %s not found", info->className, info->methodName, origSign);

		if(Type_isPrimitive(self->func.nonudt.returnType))
		{
			/*
			 * One valid reason for not finding the method is when
			 * the return type used in the signature is a primitive and
			 * the true return type of the method is the object class that
			 * corresponds to that primitive.
			 */
			altType = Type_getObjectType(self->func.nonudt.returnType);
			realRetType = altType;
		}
		else if(strcmp(Type_getJavaTypeName(self->func.nonudt.returnType), "java.sql.ResultSet") == 0)
		{
			/*
			 * Another reason might be that we expected a ResultSetProvider
			 * but the implementation returns a ResultSetHandle that needs to be
			 * wrapped. The wrapping is internal so we retain the original
			 * return type anyway.
			 */
			altType = realRetType;
		}

		if(altType != 0)
		{
			JNI_exceptionClear();
			initStringInfo(&sign);
			buildSignature(self, &sign, altType, true);

			elog(DEBUG1, "Obtaining method %s.%s %s", info->className, info->methodName, sign.data);
			self->func.nonudt.method = JNI_getStaticMethodIDOrNull(self->clazz, info->methodName, sign.data);
	
			if(self->func.nonudt.method != 0)
				self->func.nonudt.returnType = realRetType;
		}
		if(self->func.nonudt.method == 0)
			PgObject_throwMemberError(self->clazz, info->methodName, origSign, true, true);

		if(sign.data != origSign)
			pfree(origSign);
	}
	pfree(sign.data);
}