Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;");
}
Beispiel #5
0
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");
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
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");
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #11
0
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));
}
Beispiel #12
0
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");
}
Beispiel #13
0
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);
}
Beispiel #14
0
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");
}
Beispiel #15
0
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));
}
Beispiel #16
0
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");
}
Beispiel #17
0
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);
}
Beispiel #18
0
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");
}
Beispiel #19
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);
}
Beispiel #20
0
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);
}
Beispiel #21
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;
}
Beispiel #22
0
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));
}
Beispiel #23
0
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;
}
Beispiel #24
0
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));
}
Beispiel #25
0
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");
}