Esempio n. 1
0
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);
}
Esempio n. 2
0
/**
 * @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();
}
Esempio n. 3
0
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
	}
Esempio n. 4
0
/* 
 * 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")));
	}
}