Example #1
0
/*
 * Class:     org_postgresql_pljava_internal_Backend
 * Method:    _getConfigOption
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL
JNICALL Java_org_postgresql_pljava_internal_Backend__1getConfigOption(JNIEnv* env, jclass cls, jstring jkey)
{
	jstring result = 0;
	
	BEGIN_NATIVE
	char* key = String_createNTS(jkey);
	if(key != 0)
	{
		PG_TRY();
		{
			const char *value = PG_GETCONFIGOPTION(key);
			pfree(key);
			if(value != 0)
				result = String_createJavaStringFromNTS(value);
		}
		PG_CATCH();
		{
			Exception_throw_ERROR("GetConfigOption");
		}
		PG_END_TRY();
	}
	END_NATIVE
	return result;
}
Example #2
0
/*
 * Class:     org_postgresql_pljava_internal_TupleDesc
 * Method:    _getColumnIndex
 * Signature: (JLjava/lang/String;)I;
 */
JNIEXPORT jint JNICALL
Java_org_postgresql_pljava_internal_TupleDesc__1getColumnIndex(JNIEnv* env, jclass cls, jlong _this, jstring colName)
{
	jint result = 0;

	BEGIN_NATIVE
	char* name = String_createNTS(colName);
	if(name != 0)
	{
		Ptr2Long p2l;
		p2l.longVal = _this;
		PG_TRY();
		{
			result = SPI_fnumber((TupleDesc)p2l.ptrVal, name);
			if(result == SPI_ERROR_NOATTRIBUTE)
			{
				Exception_throw(ERRCODE_UNDEFINED_COLUMN,
					"Tuple has no attribute \"%s\"", name);
			}
			pfree(name);
		}
		PG_CATCH();
		{
			Exception_throw_ERROR("SPI_fnumber");
		}
		PG_END_TRY();
	}
	END_NATIVE
	return result;
}
Example #3
0
Datum UDT_output(UDT udt, PG_FUNCTION_ARGS)
{
	char* txt;

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

	if(Type_getLength((Type)udt) == -2)
	{
		txt = PG_GETARG_CSTRING(0);
		if(txt != 0)
			txt = pstrdup(txt);
	}
	else
	{
		jobject value = _UDT_coerceDatum((Type)udt, PG_GETARG_DATUM(0)).l;
		jstring jstr  = (jstring)JNI_callObjectMethod(value, udt->toString);

		MemoryContext currCtx = Invocation_switchToUpperContext();
		txt = String_createNTS(jstr);
		MemoryContextSwitchTo(currCtx);

		JNI_deleteLocalRef(value);
		JNI_deleteLocalRef(jstr);
	}
	PG_RETURN_CSTRING(txt);
}
Example #4
0
File: SPI.c Project: tada/pljava
/*
 * Class:     org_postgresql_pljava_internal_SPI
 * Method:    _exec
 * Signature: (JLjava/lang/String;I)I
 */
JNIEXPORT jint JNICALL
Java_org_postgresql_pljava_internal_SPI__1exec(JNIEnv* env, jclass cls, jlong threadId, jstring cmd, jint count)
{
	jint result = 0;

	BEGIN_NATIVE
	char* command = String_createNTS(cmd);
	if(command != 0)
	{
		STACK_BASE_VARS
		STACK_BASE_PUSH(threadId)
		PG_TRY();
		{
			Invocation_assertConnect();
			result = (jint)SPI_exec(command, (int)count);
			if(result < 0)
				Exception_throwSPI("exec", result);
	
		}
		PG_CATCH();
		{
			Exception_throw_ERROR("SPI_exec");
		}
		PG_END_TRY();
		pfree(command);
		STACK_BASE_POP()
	}
Example #5
0
/*
 * Class:     org_postgresql_pljava_internal_AclId
 * Method:    _fromName
 * Signature: (Ljava/lang/String;)Lorg/postgresql/pljava/internal/AclId;
 */
JNIEXPORT jobject JNICALL
Java_org_postgresql_pljava_internal_AclId__1fromName(JNIEnv* env, jclass clazz, jstring jname)
{
	jobject result = 0;
	if(jname != 0)
	{
		BEGIN_NATIVE
		PG_TRY();
		{
			char* roleName = String_createNTS(jname);
			HeapTuple roleTup = SearchSysCache(AUTHNAME, PointerGetDatum(roleName), 0, 0, 0);
			if(!HeapTupleIsValid(roleTup))
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("role \"%s\" does not exist", roleName)));

			result = AclId_create(HeapTupleGetOid(roleTup));
			ReleaseSysCache(roleTup);
		}
		PG_CATCH();
		{
			Exception_throw_ERROR("SearchSysCache");
		}
		PG_END_TRY();
		END_NATIVE
	}
Example #6
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;
}
Example #7
0
/*
 * Class:     org_postgresql_pljava_internal_Backend
 * Method:    _log
 * Signature: (ILjava/lang/String;)V
 */
JNIEXPORT void JNICALL
JNICALL Java_org_postgresql_pljava_internal_Backend__1log(JNIEnv* env, jclass cls, jint logLevel, jstring jstr)
{
	BEGIN_NATIVE_NO_ERRCHECK
	char* str = String_createNTS(jstr);
	if(str != 0)
	{
		PG_TRY();
		{
			elog(logLevel, "%s", str);
			pfree(str);
		}
		PG_CATCH();
		{
			Exception_throw_ERROR("ereport");
		}
		PG_END_TRY();
	}
	END_NATIVE
}
Example #8
0
void String_appendJavaString(StringInfoData* buf, jstring javaString)
{
	if ( 0 == javaString )
		return;
	if ( ! s_two_step_conversion )
	{
		jobject charbuf = JNI_callStaticObjectMethodLocked(s_CharBuffer_class,
			s_CharBuffer_wrap, javaString);
		appendCharBuffer(buf, charbuf);
		JNI_deleteLocalRef(charbuf);
	}
	else
	{
		char* dbEnc = String_createNTS(javaString);
		if ( 0 == dbEnc ) /* this can happen if a JNI call fails */
			return;
		appendStringInfoString(buf, dbEnc);
		pfree(dbEnc);
	}
}
Example #9
0
Datum _String_coerceObject(Type self, jobject jstr)
{
	char* tmp;
	Datum ret;
	if(jstr == 0)
		return 0;

	jstr = JNI_callObjectMethod(jstr, s_Object_toString);
	if(JNI_exceptionCheck())
		return 0;

	tmp = String_createNTS(jstr);
	JNI_deleteLocalRef(jstr);

	ret = FunctionCall3(
					&((String)self)->textInput,
					CStringGetDatum(tmp),
					ObjectIdGetDatum(((String)self) -> Type_extension.typeId /* elementType */ ),
					Int32GetDatum(-1));
	pfree(tmp);
	return ret;
}
Example #10
0
static Datum coerceScalarObject(UDT self, jobject value)
{
	Datum result;
	int32 dataLen = Type_getLength((Type)self);
	if(dataLen == -2)
	{
		jstring jstr = (jstring)JNI_callObjectMethod(value, self->toString);
		char* tmp = String_createNTS(jstr);
		result = CStringGetDatum(tmp);
		JNI_deleteLocalRef(jstr);
	}
	else
	{
		jobject outputStream;
		StringInfoData buffer;
		bool passByValue = Type_isByValue((Type)self);
		MemoryContext currCtx = Invocation_switchToUpperContext();

		initStringInfo(&buffer);

		if(dataLen < 0)
			/*
			 * Reserve space for an int32 at the beginning. We are building
			 * a varlena
			 */
			appendBinaryStringInfo(&buffer, (char*)&dataLen, sizeof(int32));

		outputStream = SQLOutputToChunk_create(&buffer);
		JNI_callVoidMethod(value, self->writeSQL, outputStream);
		SQLOutputToChunk_close(outputStream);
		MemoryContextSwitchTo(currCtx);

		if(dataLen < 0)
		{
			/* Assign the correct length.
			 */
#if PG_VERSION_NUM < 80300
			VARATT_SIZEP(buffer.data) = buffer.len;
#else
			SET_VARSIZE(buffer.data, buffer.len);
#endif
		}
		else if(dataLen != buffer.len)
		{
			ereport(ERROR, (
				errcode(ERRCODE_CANNOT_COERCE),
				errmsg("UDT for Oid %d produced image with incorrect size. Expected %d, was %d",
					Type_getOid((Type)self), dataLen, buffer.len)));
		}
		if (passByValue) {
			memset(&result, 0, SIZEOF_DATUM);
			/* pass by value data is stored in the least
			 * significant bits of a Datum. */
#ifdef WORDS_BIGENDIAN
			memcpy(&result + SIZEOF_DATUM - dataLen, buffer.data, dataLen);
#else
			memcpy(&result, buffer.data, dataLen);
#endif
		} else {
			result = PointerGetDatum(buffer.data);
		}

	}
	return result;
}
Example #11
0
/* Make this datatype available to the postgres system.
 */
UDT UDT_registerUDT(jclass clazz, Oid typeId, Form_pg_type pgType, TupleDesc td, bool isJavaBasedScalar)
{
	jstring jcn;
	MemoryContext currCtx;
	HeapTuple nspTup;
	Form_pg_namespace nspStruct;
	TypeClass udtClass;
	UDT udt;
	Size signatureLen;
	jstring sqlTypeName;
	char* className;
	char* classSignature;
	char* sp;
	const char* cp;
	const char* tp;
	char c;

	Type existing = Type_fromOidCache(typeId);
	if(existing != 0)
	{
		if(existing->typeClass->coerceDatum != _UDT_coerceDatum)
		{
			ereport(ERROR, (
				errcode(ERRCODE_CANNOT_COERCE),
				errmsg("Attempt to register UDT with Oid %d failed. Oid appoints a non UDT type", typeId)));
		}
		return (UDT)existing;
	}

	nspTup = PgObject_getValidTuple(NAMESPACEOID, pgType->typnamespace, "namespace");
	nspStruct = (Form_pg_namespace)GETSTRUCT(nspTup);

	/* Concatenate namespace + '.' + typename
	 */
	cp = NameStr(nspStruct->nspname);
	tp = NameStr(pgType->typname);
	sp = palloc(strlen(cp) + strlen(tp) + 2);
	sprintf(sp, "%s.%s", cp, tp);
	sqlTypeName = String_createJavaStringFromNTS(sp);
	pfree(sp);

	ReleaseSysCache(nspTup);

	/* Create a Java Signature String from the class name
	 */
	jcn = JNI_callObjectMethod(clazz, Class_getName);
	currCtx = MemoryContextSwitchTo(TopMemoryContext);
	className = String_createNTS(jcn);
	JNI_deleteLocalRef(jcn);

	signatureLen = strlen(className) + 2;
	classSignature = palloc(signatureLen + 1);
	MemoryContextSwitchTo(currCtx);

	sp = classSignature;
	cp = className;
	*sp++ = 'L';
	while((c = *cp++) != 0)
	{
		if(c == '.')
			c = '/';
		*sp++ = c;
	}
	*sp++ = ';';
	*sp = 0;

	udtClass = TypeClass_alloc2("type.UDT", sizeof(struct TypeClass_), sizeof(struct UDT_));

	udtClass->JNISignature   = classSignature;
	udtClass->javaTypeName   = className;
	udtClass->javaClass      = JNI_newGlobalRef(clazz);
	udtClass->canReplaceType = _Type_canReplaceType;
	udtClass->coerceDatum    = _UDT_coerceDatum;
	udtClass->coerceObject   = _UDT_coerceObject;

	udt = (UDT)TypeClass_allocInstance2(udtClass, typeId, pgType);
	udt->sqlTypeName = JNI_newGlobalRef(sqlTypeName);
	JNI_deleteLocalRef(sqlTypeName);

	udt->init     = PgObject_getJavaMethod(clazz, "<init>", "()V");

	if(isJavaBasedScalar)
	{
		/* A scalar mapping that is implemented in Java will have the static method:
		 * 
		 *   T parse(String stringRep, String sqlTypeName);
		 * 
		 * and a matching:
		 * 
		 *   String toString();
		 * 
		 * instance method. A pure mapping (i.e. no Java I/O methods) will not have
		 * this.
		 */
		udt->toString = PgObject_getJavaMethod(clazz, "toString", "()Ljava/lang/String;");
	
		/* The parse method is a static method on the class with the signature
		 * (Ljava/lang/String;Ljava/lang/String;)<classSignature>
		 */
		sp = palloc(signatureLen + 40);
		strcpy(sp, "(Ljava/lang/String;Ljava/lang/String;)");
		strcpy(sp + 38, classSignature);
		udt->parse = PgObject_getStaticJavaMethod(clazz, "parse", sp);
		pfree(sp);
	}
	else
	{
		udt->toString = 0;
		udt->parse = 0;
	}

	udt->tupleDesc = td;
	udt->readSQL = PgObject_getJavaMethod(clazz, "readSQL", "(Ljava/sql/SQLInput;Ljava/lang/String;)V");
	udt->writeSQL = PgObject_getJavaMethod(clazz, "writeSQL", "(Ljava/sql/SQLOutput;)V");
	Type_registerType(className, (Type)udt);
	return udt;
}