Beispiel #1
0
static bool _Array_canReplaceType(Type self, Type other)
{
	Type oe = Type_getElementType(other);
	if ( oe == 0 )
		return false;
	return Type_canReplaceType(Type_getElementType(self), oe);
}
Beispiel #2
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 #3
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)));
}