void String_initialize(void) { s_Object_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass("java/lang/Object")); s_Object_toString = PgObject_getJavaMethod(s_Object_class, "toString", "()Ljava/lang/String;"); s_String_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass("java/lang/String")); s_StringClass = TypeClass_alloc2("type.String", sizeof(struct TypeClass_), sizeof(struct String_)); s_StringClass->JNISignature = "Ljava/lang/String;"; s_StringClass->javaTypeName = "java.lang.String"; s_StringClass->canReplaceType = _String_canReplaceType; s_StringClass->coerceDatum = _String_coerceDatum; s_StringClass->coerceObject = _String_coerceObject; /* * Frame push/pop hoisted here out of String_initialize_codec to mollify * pre-C99 compilers that don't want that function to have declarations * after a statement. */ JNI_pushLocalFrame(16); String_initialize_codec(); JNI_popLocalFrame(NULL); /* * Registering known types will increase the performance * a bit. The "default" is used when all else fails. */ Type_registerType2(TEXTOID, 0, String_obtain); Type_registerType2(CSTRINGOID, 0, String_obtain); Type_registerType2(BPCHAROID, 0, String_obtain); Type_registerType2(NAMEOID, 0, String_obtain); Type_registerType2(VARCHAROID, "java.lang.String", String_obtain); }
void Double_initialize(void) { Type t_double; Type t_Double; TypeClass cls; s_Double_class = JNI_newGlobalRef(PgObject_getJavaClass("java/lang/Double")); s_DoubleArray_class = JNI_newGlobalRef(PgObject_getJavaClass("[Ljava/lang/Double;")); s_Double_init = PgObject_getJavaMethod(s_Double_class, "<init>", "(D)V"); s_Double_doubleValue = PgObject_getJavaMethod(s_Double_class, "doubleValue", "()D"); cls = TypeClass_alloc("type.Double"); cls->canReplaceType = _Double_canReplace; cls->JNISignature = "Ljava/lang/Double;"; cls->javaTypeName = "java.lang.Double"; cls->coerceDatum = _Double_coerceDatum; cls->coerceObject = _Double_coerceObject; t_Double = TypeClass_allocInstance(cls, FLOAT8OID); cls = TypeClass_alloc("type.double"); cls->JNISignature = "D"; cls->javaTypeName = "double"; cls->invoke = _double_invoke; cls->coerceDatum = _double_coerceDatum; cls->coerceObject = _Double_coerceObject; cls->createArrayType = _double_createArrayType; s_doubleClass = cls; t_double = TypeClass_allocInstance(cls, FLOAT8OID); t_double->objectType = t_Double; Type_registerType("double", t_double); Type_registerType("java.lang.Double", t_Double); }
void Function_initialize(void) { s_funcMap = HashMap_create(59, TopMemoryContext); s_Loader_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/sqlj/Loader")); s_Loader_getSchemaLoader = PgObject_getStaticJavaMethod(s_Loader_class, "getSchemaLoader", "(Ljava/lang/String;)Ljava/lang/ClassLoader;"); s_Loader_getTypeMap = PgObject_getStaticJavaMethod(s_Loader_class, "getTypeMap", "(Ljava/lang/String;)Ljava/util/Map;"); s_ClassLoader_class = JNI_newGlobalRef(PgObject_getJavaClass("java/lang/ClassLoader")); s_ClassLoader_loadClass = PgObject_getJavaMethod(s_ClassLoader_class, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); s_FunctionClass = PgObjectClass_create("Function", sizeof(struct Function_), _Function_finalize); }
void Type_initialize(void) { s_typeByOid = HashMap_create(59, TopMemoryContext); s_obtainerByOid = HashMap_create(59, TopMemoryContext); s_obtainerByJavaName = HashMap_create(59, TopMemoryContext); String_initialize(); Any_initialize(); Coerce_initialize(); Void_initialize(); Boolean_initialize(); Byte_initialize(); Short_initialize(); Integer_initialize(); Long_initialize(); Float_initialize(); Double_initialize(); BigDecimal_initialize(); Date_initialize(); Time_initialize(); Timestamp_initialize(); Oid_initialize(); AclId_initialize(); ErrorData_initialize(); LargeObject_initialize(); byte_array_initialize(); JavaWrapper_initialize(); ExecutionPlan_initialize(); Portal_initialize(); TriggerData_initialize(); Relation_initialize(); TupleDesc_initialize(); Tuple_initialize(); TupleTable_initialize(); Composite_initialize(); s_Map_class = JNI_newGlobalRef(PgObject_getJavaClass("java/util/Map")); s_Map_get = PgObject_getJavaMethod(s_Map_class, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); s_Iterator_class = JNI_newGlobalRef(PgObject_getJavaClass("java/util/Iterator")); s_Iterator_hasNext = PgObject_getJavaMethod(s_Iterator_class, "hasNext", "()Z"); s_Iterator_next = PgObject_getJavaMethod(s_Iterator_class, "next", "()Ljava/lang/Object;"); }
void byte_array_initialize(void) { TypeClass cls = TypeClass_alloc("type.byte[]"); cls->JNISignature = "[B"; cls->javaTypeName = "byte[]"; cls->coerceDatum = _byte_array_coerceDatum; cls->coerceObject = _byte_array_coerceObject; Type_registerType("byte[]", TypeClass_allocInstance(cls, BYTEAOID)); s_byteArray_class = JNI_newGlobalRef(PgObject_getJavaClass("[B")); s_BlobValue_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/jdbc/BlobValue")); s_BlobValue_length = PgObject_getJavaMethod(s_BlobValue_class, "length", "()J"); s_BlobValue_getContents = PgObject_getJavaMethod(s_BlobValue_class, "getContents", "(Ljava/nio/ByteBuffer;)V"); }
void Timestamp_initialize(void) { TypeClass cls; s_Timestamp_class = JNI_newGlobalRef(PgObject_getJavaClass("java/sql/Timestamp")); s_Timestamp_init = PgObject_getJavaMethod(s_Timestamp_class, "<init>", "(J)V"); s_Timestamp_getNanos = PgObject_getJavaMethod(s_Timestamp_class, "getNanos", "()I"); s_Timestamp_getTime = PgObject_getJavaMethod(s_Timestamp_class, "getTime", "()J"); s_Timestamp_setNanos = PgObject_getJavaMethod(s_Timestamp_class, "setNanos", "(I)V"); cls = TypeClass_alloc("type.Timestamp"); cls->JNISignature = "Ljava/sql/Timestamp;"; cls->javaTypeName = "java.sql.Timestamp"; cls->canReplaceType = _Timestamp_canReplaceType; cls->coerceDatum = _Timestamp_coerceDatum; cls->coerceObject = _Timestamp_coerceObject; Type_registerType(0, TypeClass_allocInstance(cls, TIMESTAMPOID)); s_TimestampClass = cls; cls = TypeClass_alloc("type.Timestamptz"); cls->JNISignature = "Ljava/sql/Timestamp;"; cls->javaTypeName = "java.sql.Timestamp"; cls->canReplaceType = _Timestamptz_canReplaceType; cls->coerceDatum = _Timestamptz_coerceDatum; cls->coerceObject = _Timestamptz_coerceObject; Type_registerType("java.sql.Timestamp", TypeClass_allocInstance(cls, TIMESTAMPTZOID)); s_TimestamptzClass = cls; }
void Integer_initialize(void) { Type t_int; Type t_Integer; TypeClass cls; s_Integer_class = JNI_newGlobalRef(PgObject_getJavaClass("java/lang/Integer")); s_Integer_init = PgObject_getJavaMethod(s_Integer_class, "<init>", "(I)V"); s_Integer_intValue = PgObject_getJavaMethod(s_Integer_class, "intValue", "()I"); cls = TypeClass_alloc("type.Integer"); cls->canReplaceType = _Integer_canReplace; cls->JNISignature = "Ljava/lang/Integer;"; cls->javaTypeName = "java.lang.Integer"; cls->coerceDatum = _Integer_coerceDatum; cls->coerceObject = _Integer_coerceObject; t_Integer = TypeClass_allocInstance(cls, INT4OID); cls = TypeClass_alloc("type.int"); cls->JNISignature = "I"; cls->javaTypeName = "int"; cls->invoke = _int_invoke; cls->coerceDatum = _int_coerceDatum; cls->coerceObject = _Integer_coerceObject; cls->createArrayType = _int_createArrayType; s_intClass = cls; t_int = TypeClass_allocInstance(cls, INT4OID); t_int->objectType = t_Integer; Type_registerType("int", t_int); Type_registerType("java.lang.Integer", t_Integer); }
void TupleTable_initialize(void) { s_TupleTable_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/TupleTable")); s_TupleTable_init = PgObject_getJavaMethod( s_TupleTable_class, "<init>", "(Lorg/postgresql/pljava/internal/TupleDesc;[Lorg/postgresql/pljava/internal/Tuple;)V"); }
void Boolean_initialize(void) { Type t_boolean; Type t_Boolean; TypeClass cls; s_Boolean_class = JNI_newGlobalRef(PgObject_getJavaClass("java/lang/Boolean")); s_Boolean_init = PgObject_getJavaMethod(s_Boolean_class, "<init>", "(Z)V"); s_Boolean_booleanValue = PgObject_getJavaMethod(s_Boolean_class, "booleanValue", "()Z"); cls = TypeClass_alloc("type.Boolean"); cls->canReplaceType = _Boolean_canReplace; cls->JNISignature = "Ljava/lang/Boolean;"; cls->javaTypeName = "java.lang.Boolean"; cls->coerceDatum = _Boolean_coerceDatum; cls->coerceObject = _Boolean_coerceObject; t_Boolean = TypeClass_allocInstance(cls, BOOLOID); cls = TypeClass_alloc("type.boolean"); cls->JNISignature = "Z"; cls->javaTypeName = "boolean"; cls->invoke = _boolean_invoke; cls->coerceDatum = _boolean_coerceDatum; cls->coerceObject = _Boolean_coerceObject; cls->createArrayType = _boolean_createArrayType; s_booleanClass = cls; t_boolean = TypeClass_allocInstance(cls, BOOLOID); t_boolean->objectType = t_Boolean; Type_registerType("boolean", t_boolean); Type_registerType("java.lang.Boolean", t_Boolean); }
jclass Type_getJavaClass(Type self) { TypeClass typeClass = self->typeClass; if(typeClass->javaClass == 0) { jclass cls; const char* cp = typeClass->JNISignature; if(cp == 0 || *cp == 0) ereport(ERROR, ( errmsg("Type '%s' has no corresponding java class", PgObjectClass_getName((PgObjectClass)typeClass)))); if(*cp == 'L') { /* L<object name>; should be just <object name>. Strange * since the L and ; are retained if its an array. */ int len = strlen(cp) - 2; char* bp = palloc(len + 1); memcpy(bp, cp + 1, len); bp[len] = 0; cls = PgObject_getJavaClass(bp); pfree(bp); } else cls = PgObject_getJavaClass(cp); typeClass->javaClass = JNI_newGlobalRef(cls); JNI_deleteLocalRef(cls); } return typeClass->javaClass; }
void Tuple_initialize(void) { TypeClass cls; JNINativeMethod methods[] = { { "_getObject", "(JJILjava/lang/Class;)Ljava/lang/Object;", Java_org_postgresql_pljava_internal_Tuple__1getObject }, { "_free", "(J)V", Java_org_postgresql_pljava_internal_Tuple__1free }, { 0, 0, 0 }}; s_Tuple_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/Tuple")); PgObject_registerNatives2(s_Tuple_class, methods); s_Tuple_init = PgObject_getJavaMethod(s_Tuple_class, "<init>", "(J)V"); cls = JavaWrapperClass_alloc("type.Tuple"); cls->JNISignature = "Lorg/postgresql/pljava/internal/Tuple;"; cls->javaTypeName = "org.postgresql.pljava.internal.Tuple"; cls->coerceDatum = _Tuple_coerceDatum; Type_registerType("org.postgresql.pljava.internal.Tuple", TypeClass_allocInstance(cls, InvalidOid)); }
void InstallHelper_initialize() { s_InstallHelper_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass( "org/postgresql/pljava/internal/InstallHelper")); s_InstallHelper_hello = PgObject_getStaticJavaMethod(s_InstallHelper_class, "hello", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;)Ljava/lang/String;"); s_InstallHelper_groundwork = PgObject_getStaticJavaMethod( s_InstallHelper_class, "groundwork", "(Ljava/lang/String;ZZ)V"); }
void String_initialize(void) { s_Object_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass("java/lang/Object")); s_Object_toString = PgObject_getJavaMethod(s_Object_class, "toString", "()Ljava/lang/String;"); s_String_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass("java/lang/String")); s_StringClass = TypeClass_alloc2("type.String", sizeof(struct TypeClass_), sizeof(struct String_)); s_StringClass->JNISignature = "Ljava/lang/String;"; s_StringClass->javaTypeName = "java.lang.String"; s_StringClass->canReplaceType = _String_canReplaceType; s_StringClass->coerceDatum = _String_coerceDatum; s_StringClass->coerceObject = _String_coerceObject; /* * Registering known types will increase the performance * a bit. The "default" is used when all else fails. */ Type_registerType2(TEXTOID, 0, String_obtain); Type_registerType2(CSTRINGOID, 0, String_obtain); Type_registerType2(BPCHAROID, 0, String_obtain); Type_registerType2(NAMEOID, 0, String_obtain); Type_registerType2(VARCHAROID, "java.lang.String", String_obtain); }
void SQLInputFromChunk_initialize(void) { JNINativeMethod methods[] = { { "_readByte", "(JI)I", Java_org_postgresql_pljava_jdbc_SQLInputFromChunk__1readByte }, { "_readBytes", "(JI[BI)V", Java_org_postgresql_pljava_jdbc_SQLInputFromChunk__1readBytes }, { 0, 0, 0 }}; s_SQLInputFromChunk_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/jdbc/SQLInputFromChunk")); PgObject_registerNatives2(s_SQLInputFromChunk_class, methods); s_SQLInputFromChunk_init = PgObject_getJavaMethod(s_SQLInputFromChunk_class, "<init>", "(JI)V"); s_SQLInputFromChunk_close = PgObject_getJavaMethod(s_SQLInputFromChunk_class, "close", "()V"); }
void TupleDesc_initialize(void) { TypeClass cls; JNINativeMethod methods[] = { { "_getColumnName", "(JI)Ljava/lang/String;", Java_org_postgresql_pljava_internal_TupleDesc__1getColumnName }, { "_getColumnIndex", "(JLjava/lang/String;)I", Java_org_postgresql_pljava_internal_TupleDesc__1getColumnIndex }, { "_formTuple", "(J[Ljava/lang/Object;)Lorg/postgresql/pljava/internal/Tuple;", Java_org_postgresql_pljava_internal_TupleDesc__1formTuple }, { "_getOid", "(JI)Lorg/postgresql/pljava/internal/Oid;", Java_org_postgresql_pljava_internal_TupleDesc__1getOid }, { "_free", "(J)V", Java_org_postgresql_pljava_internal_TupleDesc__1free }, { 0, 0, 0 }}; s_TupleDesc_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/TupleDesc")); PgObject_registerNatives2(s_TupleDesc_class, methods); s_TupleDesc_init = PgObject_getJavaMethod(s_TupleDesc_class, "<init>", "(JI)V"); cls = JavaWrapperClass_alloc("type.TupleDesc"); cls->JNISignature = "Lorg/postgresql/pljava/internal/TupleDesc;"; cls->javaTypeName = "org.postgresql.pljava.internal.TupleDesc"; cls->coerceDatum = _TupleDesc_coerceDatum; Type_registerType("org.postgresql.pljava.internal.TupleDesc", TypeClass_allocInstance(cls, InvalidOid)); }
void AclId_initialize(void) { JNINativeMethod methods[] = { { "_getUser", "()Lorg/postgresql/pljava/internal/AclId;", Java_org_postgresql_pljava_internal_AclId__1getUser }, { "_getOuterUser", "()Lorg/postgresql/pljava/internal/AclId;", Java_org_postgresql_pljava_internal_AclId__1getOuterUser }, { "_fromName", "(Ljava/lang/String;)Lorg/postgresql/pljava/internal/AclId;", Java_org_postgresql_pljava_internal_AclId__1fromName }, { "_getName", "()Ljava/lang/String;", Java_org_postgresql_pljava_internal_AclId__1getName }, { "_hasSchemaCreatePermission", "(Lorg/postgresql/pljava/internal/Oid;)Z", Java_org_postgresql_pljava_internal_AclId__1hasSchemaCreatePermission }, { "_isSuperuser", "()Z", Java_org_postgresql_pljava_internal_AclId__1isSuperuser }, { 0, 0, 0 }}; s_AclId_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/AclId")); PgObject_registerNatives2(s_AclId_class, methods); s_AclId_init = PgObject_getJavaMethod(s_AclId_class, "<init>", "(I)V"); s_AclId_m_native = PgObject_getJavaField(s_AclId_class, "m_native", "I"); }
void JavaWrapper_initialize(void) { JNINativeMethod methods[] = { { "_free", "(J)V", Java_org_postgresql_pljava_internal_JavaWrapper__1free }, { 0, 0, 0 } }; s_JavaWrapper_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/JavaWrapper")); PgObject_registerNatives2(s_JavaWrapper_class, methods); s_JavaWrapper_m_pointer = PgObject_getJavaField(s_JavaWrapper_class, "m_pointer", "J"); JavaMemoryContext = AllocSetContextCreate(TopMemoryContext, "PL/Java", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); }
void Relation_initialize(void) { JNINativeMethod methods[] = { { "_free", "(J)V", Java_org_postgresql_pljava_internal_Relation__1free }, { "_getName", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_Relation__1getName }, { "_getSchema", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_Relation__1getSchema }, { "_getTupleDesc", "(J)Lorg/postgresql/pljava/internal/TupleDesc;", Java_org_postgresql_pljava_internal_Relation__1getTupleDesc }, { "_modifyTuple", "(JJ[I[Ljava/lang/Object;)Lorg/postgresql/pljava/internal/Tuple;", Java_org_postgresql_pljava_internal_Relation__1modifyTuple }, { 0, 0, 0 } }; s_Relation_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/Relation")); PgObject_registerNatives2(s_Relation_class, methods); s_Relation_init = PgObject_getJavaMethod(s_Relation_class, "<init>", "(J)V"); }
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); }
Datum Type_invokeSRF(Type self, jclass cls, jmethodID method, jvalue* args, PG_FUNCTION_ARGS) { bool hasRow; CallContextData* ctxData; FuncCallContext* context; MemoryContext currCtx; /* stuff done only on the first call of the function */ if(SRF_IS_FIRSTCALL()) { jobject tmp; /* create a function context for cross-call persistence */ context = SRF_FIRSTCALL_INIT(); currCtx = MemoryContextSwitchTo(context->multi_call_memory_ctx); /* Call the declared Java function. It returns an instance that can produce * the rows. */ tmp = Type_getSRFProducer(self, cls, method, args); if(tmp == 0) { Invocation_assertDisconnect(); MemoryContextSwitchTo(currCtx); fcinfo->isnull = true; SRF_RETURN_DONE(context); } ctxData = (CallContextData*)palloc(sizeof(CallContextData)); context->user_fctx = ctxData; ctxData->elemType = self; ctxData->rowProducer = JNI_newGlobalRef(tmp); JNI_deleteLocalRef(tmp); /* Some row producers will need a writable result set in order * to produce the row. If one is needed, it's created here. */ tmp = Type_getSRFCollector(self, fcinfo); if(tmp == 0) ctxData->rowCollector = 0; else { ctxData->rowCollector = JNI_newGlobalRef(tmp); JNI_deleteLocalRef(tmp); } ctxData->trusted = currentInvocation->trusted; ctxData->hasConnected = currentInvocation->hasConnected; ctxData->invocation = currentInvocation->invocation; if(ctxData->hasConnected) ctxData->spiContext = CurrentMemoryContext; else ctxData->spiContext = 0; ctxData->rowContext = AllocSetContextCreate(context->multi_call_memory_ctx, "PL/Java row context", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); /* Register callback to be called when the function ends */ RegisterExprContextCallback(((ReturnSetInfo*)fcinfo->resultinfo)->econtext, _endOfSetCB, PointerGetDatum(ctxData)); MemoryContextSwitchTo(currCtx); } context = SRF_PERCALL_SETUP(); ctxData = (CallContextData*)context->user_fctx; MemoryContextReset(ctxData->rowContext); currCtx = MemoryContextSwitchTo(ctxData->rowContext); currentInvocation->hasConnected = ctxData->hasConnected; currentInvocation->invocation = ctxData->invocation; hasRow = Type_hasNextSRF(self, ctxData->rowProducer, ctxData->rowCollector, (jint)context->call_cntr); ctxData->hasConnected = currentInvocation->hasConnected; ctxData->invocation = currentInvocation->invocation; currentInvocation->hasConnected = false; currentInvocation->invocation = 0; if(hasRow) { Datum result = Type_nextSRF(self, ctxData->rowProducer, ctxData->rowCollector); MemoryContextSwitchTo(currCtx); SRF_RETURN_NEXT(context, result); } MemoryContextSwitchTo(currCtx); /* Unregister this callback and call it manually. We do this because * otherwise it will be called when the backend is in progress of * cleaning up Portals. If we close cursors (i.e. drop portals) in * the close, then that mechanism fails since attempts are made to * delete portals more then once. */ UnregisterExprContextCallback( ((ReturnSetInfo*)fcinfo->resultinfo)->econtext, _endOfSetCB, PointerGetDatum(ctxData)); _closeIteration(ctxData); /* This is the end of the set. */ SRF_RETURN_DONE(context); }
/* 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; }
void LargeObject_initialize(void) { TypeClass cls; JNINativeMethod methods[] = { { "_create", "(I)Lorg/postgresql/pljava/internal/Oid;", Java_org_postgresql_pljava_internal_LargeObject__1create }, { "_drop", "(Lorg/postgresql/pljava/internal/Oid;)I", Java_org_postgresql_pljava_internal_LargeObject__1drop }, { "_open", "(Lorg/postgresql/pljava/internal/Oid;I)Lorg/postgresql/pljava/internal/LargeObject;", Java_org_postgresql_pljava_internal_LargeObject__1open }, { "_close", "(J)V", Java_org_postgresql_pljava_internal_LargeObject__1close }, { "_getId", "(J)Lorg/postgresql/pljava/internal/Oid;", Java_org_postgresql_pljava_internal_LargeObject__1getId }, { "_length", "(J)J", Java_org_postgresql_pljava_internal_LargeObject__1length }, { "_seek", "(JJI)J", Java_org_postgresql_pljava_internal_LargeObject__1seek }, { "_tell", "(J)J", Java_org_postgresql_pljava_internal_LargeObject__1tell }, { "_truncate", "(JJ)V", Java_org_postgresql_pljava_internal_LargeObject__1truncate }, { "_read", "(J[B)I", Java_org_postgresql_pljava_internal_LargeObject__1read }, { "_write", "(J[B)I", Java_org_postgresql_pljava_internal_LargeObject__1write }, { 0, 0, 0 } }; s_LargeObject_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/LargeObject")); PgObject_registerNatives2(s_LargeObject_class, methods); s_LargeObject_init = PgObject_getJavaMethod(s_LargeObject_class, "<init>", "(J)V"); cls = TypeClass_alloc("type.LargeObject"); cls->JNISignature = "Lorg/postgresql/pljava/internal/LargeObject;"; cls->javaTypeName = "org.postgresql.pljava.internal.LargeObject"; Type_registerType("org.postgresql.pljava.internal.LargeObject", TypeClass_allocInstance(cls, InvalidOid)); }
static void String_initialize_codec() { jmethodID string_intern = PgObject_getJavaMethod(s_String_class, "intern", "()Ljava/lang/String;"); jstring empty = JNI_newStringUTF( ""); jclass scharset_class = PgObject_getJavaClass("java/nio/charset/StandardCharsets"); jfieldID scharset_UTF_8 = PgObject_getStaticJavaField(scharset_class, "UTF_8", "Ljava/nio/charset/Charset;"); jobject u8cs = JNI_getStaticObjectField(scharset_class, scharset_UTF_8); jclass charset_class = JNI_getObjectClass(u8cs); jmethodID charset_newDecoder = PgObject_getJavaMethod(charset_class, "newDecoder", "()Ljava/nio/charset/CharsetDecoder;"); jmethodID charset_newEncoder = PgObject_getJavaMethod(charset_class, "newEncoder", "()Ljava/nio/charset/CharsetEncoder;"); jclass decoder_class = PgObject_getJavaClass("java/nio/charset/CharsetDecoder"); jclass encoder_class = PgObject_getJavaClass("java/nio/charset/CharsetEncoder"); jmethodID encoder_abpc = PgObject_getJavaMethod(encoder_class, "averageBytesPerChar", "()F"); jclass result_class = PgObject_getJavaClass("java/nio/charset/CoderResult"); jfieldID overflow = PgObject_getStaticJavaField(result_class, "OVERFLOW", "Ljava/nio/charset/CoderResult;"); jfieldID underflow = PgObject_getStaticJavaField(result_class, "UNDERFLOW", "Ljava/nio/charset/CoderResult;"); jclass buffer_class = PgObject_getJavaClass("java/nio/Buffer"); s_CharsetDecoder_instance = JNI_newGlobalRef(JNI_callObjectMethod(u8cs, charset_newDecoder)); s_CharsetEncoder_instance = JNI_newGlobalRef(JNI_callObjectMethod(u8cs, charset_newEncoder)); s_CharsetDecoder_decode = PgObject_getJavaMethod(decoder_class, "decode", "(Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;"); s_CharsetEncoder_encode = PgObject_getJavaMethod(encoder_class, "encode", "(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;Z)" "Ljava/nio/charset/CoderResult;"); s_CharsetEncoder_averageBytesPerChar = JNI_callFloatMethod(s_CharsetEncoder_instance, encoder_abpc); s_CoderResult_OVERFLOW = JNI_newGlobalRef( JNI_getStaticObjectField(result_class, overflow)); s_CoderResult_UNDERFLOW = JNI_newGlobalRef( JNI_getStaticObjectField(result_class, underflow)); s_CoderResult_throwException = PgObject_getJavaMethod(result_class, "throwException", "()V"); s_CharBuffer_class = (jclass)JNI_newGlobalRef( PgObject_getJavaClass("java/nio/CharBuffer")); s_CharBuffer_wrap = PgObject_getStaticJavaMethod(s_CharBuffer_class, "wrap", "(Ljava/lang/CharSequence;)Ljava/nio/CharBuffer;"); s_Buffer_position = PgObject_getJavaMethod(buffer_class, "position", "()I"); s_Buffer_remaining = PgObject_getJavaMethod(buffer_class, "remaining", "()I"); s_the_empty_string = JNI_newGlobalRef( JNI_callObjectMethod(empty, string_intern)); s_server_encoding = GetDatabaseEncoding(); s_two_step_conversion = PG_UTF8 != s_server_encoding; uninitialized = false; }
void TriggerData_initialize(void) { TypeClass cls; JNINativeMethod methods[] = { { "_free", "(J)V", Java_org_postgresql_pljava_internal_TriggerData__1free }, { "_getRelation", "(J)Lorg/postgresql/pljava/internal/Relation;", Java_org_postgresql_pljava_internal_TriggerData__1getRelation }, { "_getTriggerTuple", "(J)Lorg/postgresql/pljava/internal/Tuple;", Java_org_postgresql_pljava_internal_TriggerData__1getTriggerTuple }, { "_getNewTuple", "(J)Lorg/postgresql/pljava/internal/Tuple;", Java_org_postgresql_pljava_internal_TriggerData__1getNewTuple }, { "_getArguments", "(J)[Ljava/lang/String;", Java_org_postgresql_pljava_internal_TriggerData__1getArguments }, { "_getName", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_TriggerData__1getName }, { "_isFiredAfter", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredAfter }, { "_isFiredBefore", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredBefore }, { "_isFiredForEachRow", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredForEachRow }, { "_isFiredForStatement", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredForStatement }, { "_isFiredByDelete", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredByDelete }, { "_isFiredByInsert", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredByInsert }, { "_isFiredByUpdate", "(J)Z", Java_org_postgresql_pljava_internal_TriggerData__1isFiredByUpdate }, { 0, 0, 0 } }; s_TriggerData_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/TriggerData")); PgObject_registerNatives2(s_TriggerData_class, methods); s_TriggerData_init = PgObject_getJavaMethod(s_TriggerData_class, "<init>", "(J)V"); s_TriggerData_getTriggerReturnTuple = PgObject_getJavaMethod(s_TriggerData_class, "getTriggerReturnTuple", "()J"); /* Use interface name for signatures. */ cls = TypeClass_alloc("type.TriggerData"); cls->JNISignature = "Lorg/postgresql/pljava/TriggerData;"; cls->javaTypeName = "org.postgresql.pljava.TriggerData"; Type_registerType("org.postgresql.pljava.TriggerData", TypeClass_allocInstance(cls, InvalidOid)); }
void ErrorData_initialize(void) { JNINativeMethod methods[] = { { "_getErrorLevel", "(J)I", Java_org_postgresql_pljava_internal_ErrorData__1getErrorLevel }, { "_isOutputToServer", "(J)Z", Java_org_postgresql_pljava_internal_ErrorData__1isOutputToServer }, { "_isOutputToClient", "(J)Z", Java_org_postgresql_pljava_internal_ErrorData__1isOutputToClient }, { "_isShowFuncname", "(J)Z", Java_org_postgresql_pljava_internal_ErrorData__1isShowFuncname }, { "_getFilename", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getFilename }, { "_getLineno", "(J)I", Java_org_postgresql_pljava_internal_ErrorData__1getLineno }, { "_getFuncname", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getFuncname }, { "_getSqlState", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getSqlState }, { "_getMessage", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getMessage }, { "_getDetail", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getDetail }, { "_getHint", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getHint }, { "_getContextMessage", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getContextMessage }, { "_getCursorPos", "(J)I", Java_org_postgresql_pljava_internal_ErrorData__1getCursorPos }, { "_getInternalPos", "(J)I", Java_org_postgresql_pljava_internal_ErrorData__1getInternalPos }, { "_getInternalQuery", "(J)Ljava/lang/String;", Java_org_postgresql_pljava_internal_ErrorData__1getInternalQuery }, { "_getSavedErrno", "(J)I", Java_org_postgresql_pljava_internal_ErrorData__1getSavedErrno }, { "_free", "(J)V", Java_org_postgresql_pljava_internal_ErrorData__1free }, { 0, 0, 0 } }; s_ErrorData_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/ErrorData")); PgObject_registerNatives2(s_ErrorData_class, methods); s_ErrorData_init = PgObject_getJavaMethod(s_ErrorData_class, "<init>", "(J)V"); s_ErrorData_getNativePointer = PgObject_getJavaMethod(s_ErrorData_class, "getNativePointer", "()J"); }