Пример #1
0
Datum UDT_input(UDT udt, PG_FUNCTION_ARGS)
{
	jstring jstr;
	jobject obj;
	char* txt;

	if(!UDT_isScalar(udt))
		ereport(ERROR, (
			errcode(ERRCODE_CANNOT_COERCE),
			errmsg("UDT with Oid %d is not scalar", Type_getOid((Type)udt))));

	txt = PG_GETARG_CSTRING(0);

	if(Type_getLength((Type)udt) == -2)
	{
		if(txt != 0)
			txt = pstrdup(txt);
		PG_RETURN_CSTRING(txt);
	}
	jstr = String_createJavaStringFromNTS(txt);
	obj  = JNI_callStaticObjectMethod(Type_getJavaClass((Type)udt), udt->parse, jstr, udt->sqlTypeName);
	JNI_deleteLocalRef(jstr);

	return _UDT_coerceObject((Type)udt, obj);
}
Пример #2
0
static jobject coerceScalarDatum(UDT self, Datum arg)
{
	jobject result;
	int32 dataLen = Type_getLength((Type)self);
	jclass javaClass = Type_getJavaClass((Type)self);
	bool isJavaBasedScalar = 0 != self->toString;

	if(dataLen == -2)
	{
		/* Data is a zero terminated string
		 */
		jstring jstr = String_createJavaStringFromNTS(DatumGetCString(arg));
		result = JNI_callStaticObjectMethod(javaClass, self->parse, jstr, self->sqlTypeName);
		JNI_deleteLocalRef(jstr);
	}
	else
	{
		char* data;
		jobject inputStream;
		if(dataLen == -1)
		{
			/* Data is a varlena struct
			*/
			bytea* bytes = DatumGetByteaP(arg);
			dataLen = VARSIZE(bytes) - VARHDRSZ;
			data    = VARDATA(bytes);
		}
		else
		{
			bool passByValue = Type_isByValue((Type)self);
			/* Data is a binary chunk of size dataLen
			 */
			if (passByValue)
			{
				/* pass by value data is stored in the least
				 * significant bits of a Datum. */
#ifdef WORDS_BIGENDIAN
				data = ((char *)(&arg)) + SIZEOF_DATUM - dataLen;
#else
				data = ((char *)(&arg));
#endif
			}
			else
			{
				data = DatumGetPointer(arg);
			}
		}
		result = JNI_newObject(javaClass, self->init);

		inputStream = SQLInputFromChunk_create(data, dataLen,
			isJavaBasedScalar);
		JNI_callVoidMethod(result, self->readSQL, inputStream, self->sqlTypeName);
		SQLInputFromChunk_close(inputStream);
	}
	return result;
}
Пример #3
0
char *InstallHelper_hello()
{
	char pathbuf[MAXPGPATH];
	Invocation ctx;
	jstring nativeVer;
	jstring user;
	jstring dbname;
	jstring clustername;
	jstring ddir;
	jstring ldir;
	jstring sdir;
	jstring edir;
	jstring greeting;
	char *greetingC;
	char const *clusternameC = pljavaClusterName();

	Invocation_pushBootContext(&ctx);
	nativeVer = String_createJavaStringFromNTS(SO_VERSION_STRING);
	user = String_createJavaStringFromNTS(MyProcPort->user_name);
	dbname = String_createJavaStringFromNTS(MyProcPort->database_name);
	if ( '\0' == *clusternameC )
		clustername = NULL;
	else
		clustername = String_createJavaStringFromNTS(clusternameC);

	ddir = String_createJavaStringFromNTS(DataDir);

	get_pkglib_path(my_exec_path, pathbuf);
	ldir = String_createJavaStringFromNTS(pathbuf);

	get_share_path(my_exec_path, pathbuf);
	sdir = String_createJavaStringFromNTS(pathbuf);

	get_etc_path(my_exec_path, pathbuf);
	edir = String_createJavaStringFromNTS(pathbuf);

	greeting = JNI_callStaticObjectMethod(
		s_InstallHelper_class, s_InstallHelper_hello,
		nativeVer, user, dbname, clustername, ddir, ldir, sdir, edir);

	JNI_deleteLocalRef(nativeVer);
	JNI_deleteLocalRef(user);
	JNI_deleteLocalRef(dbname);
	if ( NULL != clustername )
		JNI_deleteLocalRef(clustername);
	JNI_deleteLocalRef(ddir);
	JNI_deleteLocalRef(ldir);
	JNI_deleteLocalRef(sdir);
	JNI_deleteLocalRef(edir);
	greetingC = String_createNTS(greeting);
	JNI_deleteLocalRef(greeting);
	Invocation_popBootContext();
	return greetingC;
}
Пример #4
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);
}