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); }
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; } } }
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))); }