/* * 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; }
/* * 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; }
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); }
/* * 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() }
/* * 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 }
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; }
/* * 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 }
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); } }
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; }
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; }
/* 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; }