Exemple #1
0
/* check whether the content in the given bytea is safe for mfvtransval */
void check_mfvtransval(bytea *storage) {
    size_t left_len = VARSIZE(storage);
    size_t cur_size = 0;
    size_t cur_capacity = 0;
    Oid     outFuncOid;
    bool    typIsVarLen;

    mfvtransval *mfv  = NULL;

    if (left_len < VARHDRSZ + sizeof(mfvtransval)) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }
    mfv = (mfvtransval*)VARDATA(storage);
    left_len -= VARHDRSZ + sizeof(mfvtransval);

    if (mfv->next_mfv > mfv->max_mfvs) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    if (mfv->next_offset + VARHDRSZ > VARSIZE(storage)) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    if (InvalidOid == mfv->typOid) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    getTypeOutputInfo(mfv->typOid, &outFuncOid, &typIsVarLen);
    if (mfv->outFuncOid != outFuncOid
        || mfv->typLen != get_typlen(mfv->typOid)
        || mfv->typByVal != get_typbyval(mfv->typOid)) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    if (left_len < sizeof(offsetcnt)*mfv->max_mfvs) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }
    /* offset is relative to mfvtransval */
    left_len = VARSIZE(storage) - VARHDRSZ;

    /*
     * the following checking may be inefficiency, but by doing this centrally,
     * we can avoid spreading the checking code everywhere.
     */
    for (unsigned i = 0; i < mfv->next_mfv; i ++) {
        cur_capacity = left_len - mfv->mfvs[i].offset;

        if (mfv->mfvs[i].offset > left_len) {
            elog(ERROR, "invalid transition state for mfvsketch");
        }

        cur_size = ExtractDatumLen(PointerGetDatum(MFV_DATA(mfv) + mfv->mfvs[i].offset),
            mfv->typLen, mfv->typByVal, cur_capacity);

        if (cur_size > cur_capacity) {
            elog(ERROR, "invalid transition state for mfvsketch");
        }
    }
}
Exemple #2
0
/*
 * free_attstatsslot
 *		Free data allocated by get_attstatsslot
 *
 * atttype need be valid only if values != NULL.
 */
void
free_attstatsslot(Oid atttype,
				  Datum *values, int nvalues,
				  float4 *numbers, int nnumbers)
{
	if (values)
	{
		if (!get_typbyval(atttype))
		{
			int			i;

			for (i = 0; i < nvalues; i++)
				pfree(DatumGetPointer(values[i]));
		}
		pfree(values);
	}
	if (numbers)
		pfree(numbers);
}
Exemple #3
0
/* check whether the content in the given bytea is safe for mfvtransval */
void check_mfvtransval(bytea *storage) {
    size_t left_len = VARSIZE(storage);
    Oid     outFuncOid;
    bool    typIsVarLen;

    mfvtransval *mfv  = NULL;

    if (left_len < VARHDRSZ + sizeof(mfvtransval)) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }
    mfv = (mfvtransval*)VARDATA(storage);
    left_len -= VARHDRSZ + sizeof(mfvtransval);

    if (mfv->next_mfv > mfv->max_mfvs) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    if (mfv->next_offset + VARHDRSZ > VARSIZE(storage)) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    if (InvalidOid == mfv->typOid) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    getTypeOutputInfo(mfv->typOid, &outFuncOid, &typIsVarLen);
    if (mfv->outFuncOid != outFuncOid
        || mfv->typLen != get_typlen(mfv->typOid)
        || mfv->typByVal != get_typbyval(mfv->typOid)) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }

    if (left_len < sizeof(offsetcnt)*mfv->max_mfvs) {
        elog(ERROR, "invalid transition state for mfvsketch");
    }
}
Exemple #4
0
/*!
 * Initialize an mfv sketch
 * \param max_mfvs the number of "bins" in the histogram
 * \param typOid the type ID for the column
 */
bytea *mfv_init_transval(int max_mfvs, Oid typOid)
{
    int          initial_size;
    bool         typIsVarLen;
    bytea *      transblob;
    mfvtransval *transval;

    /*
     * initialize mfvtransval, using palloc0 to zero it out.
     * if typlen is positive (fixed), size chosen accurately.
     * Else we'll do a conservative estimate of 16 bytes, and repalloc as needed.
     */
    if ((initial_size = get_typlen(typOid)) > 0)
        initial_size *= max_mfvs*get_typlen(typOid);
    else /* guess */
        initial_size = max_mfvs*16;

    transblob = (bytea *)palloc0(MFV_TRANSVAL_SZ(max_mfvs) + initial_size);

    SET_VARSIZE(transblob, MFV_TRANSVAL_SZ(max_mfvs) + initial_size);
    transval = (mfvtransval *)VARDATA(transblob);
    transval->max_mfvs = max_mfvs;
    transval->next_mfv = 0;
    transval->next_offset = MFV_TRANSVAL_SZ(max_mfvs)-VARHDRSZ;
    transval->typOid = typOid;
    getTypeOutputInfo(transval->typOid,
                      &(transval->outFuncOid),
                      &(typIsVarLen));
    transval->typLen = get_typlen(transval->typOid);
    transval->typByVal = get_typbyval(transval->typOid);
    if (!transval->outFuncOid) {
        /* no outFunc for this type! */
        elog(ERROR, "no outFunc for type %d", transval->typOid);
    }
    return(transblob);
}