Beispiel #1
0
static void setupTriggerParams(Function self, ParseResult info)
{
	if(info->parameters != 0)
		ereport(ERROR, (
			errcode(ERRCODE_SYNTAX_ERROR),
			errmsg("Triggers can not have a java parameter declaration")));

	self->func.nonudt.returnType = Type_fromJavaType(InvalidOid, "void");

	/* Parameters are not used when calling triggers.
		*/
	self->func.nonudt.numParams  = 1;
	self->func.nonudt.paramTypes = (Type*)MemoryContextAlloc(GetMemoryChunkContext(self), sizeof(Type));
	self->func.nonudt.paramTypes[0] = Type_fromJavaType(InvalidOid, "org.postgresql.pljava.TriggerData");
}
Beispiel #2
0
Type Type_fromJavaType(Oid typeId, const char* javaTypeName)
{
	CacheEntry ce = (CacheEntry)HashMap_getByString(s_obtainerByJavaName, javaTypeName);
	if(ce == 0)
	{
		int jtlen = strlen(javaTypeName) - 2;
		if(jtlen > 0 && strcmp("[]", javaTypeName + jtlen) == 0)
		{
			Type type;
			char* elemName = palloc(jtlen+1);
			memcpy(elemName, javaTypeName, jtlen);
			elemName[jtlen] = 0;
			type = Type_getArrayType(Type_fromJavaType(InvalidOid, elemName), typeId);
			pfree(elemName);
			return type;
		}
		ereport(ERROR, (
			errcode(ERRCODE_CANNOT_COERCE),
			errmsg("No java type mapping installed for \"%s\"", javaTypeName)));
	}

	return ce->type == 0
		? ce->obtainer(typeId == InvalidOid ? ce->typeId : typeId)
		: ce->type;
}
Beispiel #3
0
static void setupFunctionParams(Function self, ParseResult info, Form_pg_proc procStruct, PG_FUNCTION_ARGS)
{
	Oid* paramOids;
	MemoryContext ctx = GetMemoryChunkContext(self);
	int32 top = (int32)procStruct->pronargs;;

	self->func.nonudt.numParams = top;
	self->func.nonudt.isMultiCall = procStruct->proretset;
	self->func.nonudt.returnType = Type_fromOid(procStruct->prorettype, self->func.nonudt.typeMap);

	if(top > 0)
	{
		int idx;
		paramOids = PARAM_OIDS(procStruct);
		self->func.nonudt.paramTypes = (Type*)MemoryContextAlloc(ctx, top * sizeof(Type));

		for(idx = 0; idx < top; ++idx)
			self->func.nonudt.paramTypes[idx] = Type_fromOid(paramOids[idx], self->func.nonudt.typeMap);
	}
	else
	{
		self->func.nonudt.paramTypes = 0;
		paramOids = 0;
	}

	if(info->parameters != 0)
		parseParameters(self, paramOids, info->parameters);

	if(info->returnType != 0)
	{
		const char* jtName = Type_getJavaTypeName(self->func.nonudt.returnType);
		if(strcmp(jtName, info->returnType) != 0)
		{
			Type repl = Type_fromJavaType(Type_getOid(self->func.nonudt.returnType), info->returnType);
			if(!Type_canReplaceType(repl, self->func.nonudt.returnType))
				repl = Type_getCoerceOut(repl, self->func.nonudt.returnType);
			self->func.nonudt.returnType = repl;
		}
	}
}
Beispiel #4
0
static void parseParameters(Function self, Oid* dfltIds, const char* paramDecl)
{
	char c;
	int idx = 0;
	int top = self->func.nonudt.numParams;
	bool lastIsOut = !self->func.nonudt.isMultiCall
					&& Type_isOutParameter(self->func.nonudt.returnType);
	StringInfoData sign;
	Type deflt;
	const char* jtName;
	bool gotone = false;
	for( ; ; ++ paramDecl )
	{
		c = *paramDecl;
		/* all whitespace has already been stripped by getAS() */

		if ( '\0' != c  &&  ',' != c )
		{
			if ( ! gotone ) /* first character of a param type has been seen. */
			{
				if(idx >= top)
				{
					if(!(lastIsOut && idx == top))
						ereport(ERROR, (
							errcode(ERRCODE_SYNTAX_ERROR),
							errmsg("AS (Java): expected %d parameter types, "
							       "found more", top)));
				}
				gotone = true;
				initStringInfo(&sign);
			}
			appendStringInfoChar(&sign, c);
			continue;
		}

		if ( ! gotone )
		{
			if ( '\0' == c )
				break;
			ereport(ERROR, (
				errcode(ERRCODE_SYNTAX_ERROR),
				errmsg("AS (Java): expected parameter type, found comma")));
		}

		/* so, got one. */
		deflt = (idx == top)
			? self->func.nonudt.returnType : self->func.nonudt.paramTypes[idx];
		jtName = Type_getJavaTypeName(deflt);
		if ( strcmp(jtName, sign.data) != 0 )
		{
			Oid did;
			Type repl;
			if(idx == top)
				/*
				 * Last parameter is the OUT parameter. It has no corresponding
				 * entry in the dfltIds array.
				 */
				did = InvalidOid;
			else
				did = dfltIds[idx];

			repl = Type_fromJavaType(did, sign.data);
			if(!Type_canReplaceType(repl, deflt))
				repl = Type_getCoerceIn(repl, deflt);

			if(idx == top)
				self->func.nonudt.returnType = repl;
			else
				self->func.nonudt.paramTypes[idx] = repl;
		}
		pfree(sign.data);

		++idx;
		if ( '\0' == c )
			break;
		gotone = false;
	}

    /*
     * We are done.
     */
    if(lastIsOut)
		++top;
    if(idx != top)
		ereport(ERROR, (
			errcode(ERRCODE_SYNTAX_ERROR),
			errmsg("AS (Java): expected %d parameter types, found fewer",
				top)));
}