static Variant variant_in_int(FunctionCallInfo fcinfo, char *input, int variant_typmod) { VariantCache *cache; bool isnull; Oid intTypeOid = InvalidOid; int32 typmod = 0; text *orgType; text *orgData; VariantInt vi = palloc0(sizeof(*vi)); /* Eventually getting rid of this crap, so segregate it */ intTypeOid = getIntOid(); FmgrInfo proc; Datum composite; HeapTupleHeader composite_tuple; Oid typioparam; Oid typIoFunc; /* Cast input data to our internal composite type */ getTypeInputInfo(intTypeOid, &typIoFunc, &typioparam); fmgr_info_cxt(typIoFunc, &proc, fcinfo->flinfo->fn_mcxt); composite=InputFunctionCall(&proc, input, typioparam, typmod); /* Extract data from internal composite type */ composite_tuple=DatumGetHeapTupleHeader(composite); orgType = (text *) GetAttributeByNum( composite_tuple, 1, &isnull ); if (isnull) elog(ERROR, "original_type of variant must not be NULL"); orgData = (text *) GetAttributeByNum( composite_tuple, 2, &vi->isnull ); /* End crap */ #ifdef LONG_PARSETYPE parseTypeString(text_to_cstring(orgType), &vi->typid, &vi->typmod, false); #else parseTypeString(text_to_cstring(orgType), &vi->typid, &vi->typmod); #endif /* * Verify we've been handed a valid typmod */ variant_get_variant_name(variant_typmod, vi->typid, false); cache = get_cache(fcinfo, vi, IOFunc_input); if (!vi->isnull) /* Actually need to be using stringTypeDatum(Type tp, char *string, int32 atttypmod) */ vi->data = InputFunctionCall(&cache->proc, text_to_cstring(orgData), cache->typioparam, vi->typmod); return make_variant(vi, fcinfo, IOFunc_input); }
/** * @brief Internal function for retrieving the type ID and datum for an element * of a native composite type * * @param inID Number of function argument * @param[out] outTypeID PostgreSQL OID of the function argument's type * @param[out] outDatum PostgreSQL Datum for the function argument * * @internal * Having this as separate function isolates the PG_TRY block. Otherwise, * the compiler might warn that the longjmp could clobber local variables. */ inline void AbstractionLayer::AnyType::backendGetTypeIDAndDatumForTupleElement( uint16_t inID, Oid &outTypeID, Datum &outDatum) const { madlib_assert(mContent == NativeComposite, std::logic_error( "Inconsistency detected while converting from PostgreSQL to C++ types.")); bool exceptionOccurred = false; Oid tupType; int32 tupTypmod; TupleDesc tupDesc; bool isNull = false; PG_TRY(); { tupType = HeapTupleHeaderGetTypeId(mTupleHeader); tupTypmod = HeapTupleHeaderGetTypMod(mTupleHeader); tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod); outTypeID = tupDesc->attrs[inID]->atttypid; ReleaseTupleDesc(tupDesc); outDatum = GetAttributeByNum(mTupleHeader, inID, &isNull); } PG_CATCH(); { exceptionOccurred = true; } PG_END_TRY(); if (exceptionOccurred) throw PGException(); }
jobject HeapTupleHeader_getObject( JNIEnv* env, jlong hth, jlong jtd, jint attrNo, jclass rqcls) { jobject result = 0; HeapTupleHeader self = (HeapTupleHeader)Invocation_getWrappedPointer(hth); if(self != 0 && jtd != 0) { Ptr2Long p2l; p2l.longVal = jtd; BEGIN_NATIVE PG_TRY(); { Type type = TupleDesc_getColumnType( (TupleDesc) p2l.ptrVal, (int) attrNo); if (type != 0) { Datum binVal; bool wasNull = false; binVal = GetAttributeByNum(self, (AttrNumber)attrNo, &wasNull); if(!wasNull) result = Type_coerceDatumAs(type, binVal, rqcls).l; } } PG_CATCH(); { Exception_throw_ERROR("GetAttributeByNum"); } PG_END_TRY(); END_NATIVE }
/* * Helper function used to extract interesting information from * the state tuple. */ static void get_nb_state(HeapTupleHeader tuple, nb_classify_state *state, int nclasses) { Datum class_datum, accum_datum, total_datum; bool isnull[3]; /* * When called correctly nb_classify should never fill in the state * tuple with any invalid values, but if a user is calling the * functions by hand for some reason then something may be funny */ class_datum = GetAttributeByNum(tuple, 1, &isnull[0]); accum_datum = GetAttributeByNum(tuple, 2, &isnull[1]); total_datum = GetAttributeByNum(tuple, 3, &isnull[2]); if (isnull[0] || isnull[1] || isnull[2]) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("nb_classify: invalid accumulation state"))); } state->classes = DatumGetArrayTypeP(class_datum); state->accum = DatumGetArrayTypeP(accum_datum); state->total = DatumGetArrayTypeP(total_datum); /* All must have the correct dimensionality */ if (ARR_NDIM(state->classes) != 1 || ARR_NDIM(state->accum) != 1 || ARR_NDIM(state->total) != 1 || ARR_DIMS(state->accum)[0] != ARR_DIMS(state->classes)[0] || ARR_DIMS(state->classes)[0] != ARR_DIMS(state->classes)[0]) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("nb_classify: invalid accumulation state"))); } /* Check that lengths matchup with what was expected */ if (nclasses > 0 && ARR_DIMS(state->classes)[0] != nclasses) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("nb_classify: mismatched inter-row input lengths"))); } }