示例#1
0
/*
 * Convert to a domain type.
 */
static Datum
PLyObject_ToDomain(PLyObToDatum *arg, PyObject *plrv,
				   bool *isnull, bool inarray)
{
	Datum		result;
	PLyObToDatum *base = arg->u.domain.base;

	result = base->func(base, plrv, isnull, inarray);
	domain_check(result, *isnull, arg->typoid,
				 &arg->u.domain.domain_info, arg->mcxt);
	return result;
}
示例#2
0
static VALUE
math_sqrt(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    errno = 0;
    d0 = RFLOAT_VALUE(x);
    d = sqrt(d0);
    domain_check(d0, d, "sqrt");
    return DBL2NUM(d);
}
示例#3
0
/*
 * Convert a Python object to a PostgreSQL bool datum.	This can't go
 * through the generic conversion function, because Python attaches a
 * Boolean value to everything, more things than the PostgreSQL bool
 * type can parse.
 */
static Datum
PLyObject_ToBool(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	Datum		rv;

	Assert(plrv != Py_None);
	rv = BoolGetDatum(PyObject_IsTrue(plrv));

	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);

	return rv;
}
示例#4
0
static VALUE
math_log10(VALUE obj, VALUE x)
{
    double d0, d;

    Need_Float(x);
    errno = 0;
    d0 = RFLOAT_VALUE(x);
    d = log10(d0);
    domain_check(d0, d, "log10");
    infinity_check(x, d, "log10");
    return DBL2NUM(d);
}
示例#5
0
static VALUE
math_lgamma(VALUE obj, VALUE x)
{
    double d0, d;
    int sign;
    VALUE v;
    Need_Float(x);
    errno = 0;
    d0 = RFLOAT_VALUE(x);
    d = lgamma_r(d0, &sign);
    domain_check(d0, d, "lgamma");
    v = DBL2NUM(d);
    return rb_assoc_new(v, INT2FIX(sign));
}
示例#6
0
static Datum
PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	ArrayType  *array;
	Datum		rv;
	int			i;
	Datum	   *elems;
	bool	   *nulls;
	int			len;
	int			lbs;

	Assert(plrv != Py_None);

	if (!PySequence_Check(plrv))
		PLy_elog(ERROR, "return value of function with array return type is not a Python sequence");

	len = PySequence_Length(plrv);
	elems = palloc(sizeof(*elems) * len);
	nulls = palloc(sizeof(*nulls) * len);

	for (i = 0; i < len; i++)
	{
		PyObject   *obj = PySequence_GetItem(plrv, i);

		if (obj == Py_None)
			nulls[i] = true;
		else
		{
			nulls[i] = false;
			elems[i] = arg->elm->func(arg->elm, -1, obj);
		}
		Py_XDECREF(obj);
	}

	lbs = 1;
	array = construct_md_array(elems, nulls, 1, &len, &lbs,
							   get_base_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign);

	/*
	 * If the result type is a domain of array, the resulting array must be
	 * checked.
	 */
	rv = PointerGetDatum(array);
	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);
	return rv;
}
示例#7
0
static VALUE
math_gamma(VALUE obj, VALUE x)
{
    static const double fact_table[] = {
        /* fact(0) */ 1.0,
        /* fact(1) */ 1.0,
        /* fact(2) */ 2.0,
        /* fact(3) */ 6.0,
        /* fact(4) */ 24.0,
        /* fact(5) */ 120.0,
        /* fact(6) */ 720.0,
        /* fact(7) */ 5040.0,
        /* fact(8) */ 40320.0,
        /* fact(9) */ 362880.0,
        /* fact(10) */ 3628800.0,
        /* fact(11) */ 39916800.0,
        /* fact(12) */ 479001600.0,
        /* fact(13) */ 6227020800.0,
        /* fact(14) */ 87178291200.0,
        /* fact(15) */ 1307674368000.0,
        /* fact(16) */ 20922789888000.0,
        /* fact(17) */ 355687428096000.0,
        /* fact(18) */ 6402373705728000.0,
        /* fact(19) */ 121645100408832000.0,
        /* fact(20) */ 2432902008176640000.0,
        /* fact(21) */ 51090942171709440000.0,
        /* fact(22) */ 1124000727777607680000.0,
        /* fact(23)=25852016738884976640000 needs 56bit mantissa which is
         * impossible to represent exactly in IEEE 754 double which have
         * 53bit mantissa. */
    };
    double d0, d;
    double intpart, fracpart;
    int n;
    Need_Float(x);
    d0 = RFLOAT_VALUE(x);
    fracpart = modf(d0, &intpart);
    if (fracpart == 0.0 &&
	0 < intpart &&
	(n = (int)intpart - 1) < numberof(fact_table)) {
        return DBL2NUM(fact_table[n]);
    }
    errno = 0;
    d = tgamma(d0);
    domain_check(d0, d, "gamma");
    return DBL2NUM(d);
}
示例#8
0
static VALUE
math_log(int argc, VALUE *argv)
{
    VALUE x, base;
    double d0, d;

    rb_scan_args(argc, argv, "11", &x, &base);
    Need_Float(x);
    errno = 0;
    d0 = RFLOAT_VALUE(x);
    d = log(d0);
    if (argc == 2) {
	Need_Float(base);
	d /= log(RFLOAT_VALUE(base));
    }
    domain_check(d0, d, "log");
    infinity_check(x, d, "log");
    return DBL2NUM(d);
}
示例#9
0
/*
 * Convert a Python object to a PostgreSQL bytea datum.  This doesn't
 * go through the generic conversion function to circumvent problems
 * with embedded nulls.  And it's faster this way.
 */
static Datum
PLyObject_ToBytea(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
{
	PyObject   *volatile plrv_so = NULL;
	Datum		rv;

	Assert(plrv != Py_None);

	plrv_so = PyObject_Bytes(plrv);
	if (!plrv_so)
		PLy_elog(ERROR, "could not create bytes representation of Python object");

	PG_TRY();
	{
		char	   *plrv_sc = PyBytes_AsString(plrv_so);
		size_t		len = PyBytes_Size(plrv_so);
		size_t		size = len + VARHDRSZ;
		bytea	   *result = palloc(size);

		SET_VARSIZE(result, size);
		memcpy(VARDATA(result), plrv_sc, len);
		rv = PointerGetDatum(result);
	}
	PG_CATCH();
	{
		Py_XDECREF(plrv_so);
		PG_RE_THROW();
	}
	PG_END_TRY();

	Py_XDECREF(plrv_so);

	if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN)
		domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt);

	return rv;
}
示例#10
0
func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
                                             unsigned arity, sort * const * domain, sort * range) {
    if (num_parameters < 2 || !parameters[0].is_ast() || !is_sort(parameters[0].get_ast())) {
        m_manager->raise_exception("invalid parameters for datatype operator");
        return 0;
    }
    sort * datatype = to_sort(parameters[0].get_ast());
    if (datatype->get_family_id() != m_family_id ||
        datatype->get_decl_kind() != DATATYPE_SORT) {
        m_manager->raise_exception("invalid parameters for datatype operator");
        return 0;
    }
    for (unsigned i = 1; i < num_parameters; i++) {
        if (!parameters[i].is_int()) {
            m_manager->raise_exception("invalid parameters for datatype operator");
            return 0;
        }
    }
    unsigned c_idx            = parameters[1].get_int();
    unsigned tid              = datatype->get_parameter(1).get_int();
    unsigned o                = datatype->get_parameter(2 + 2 * tid + 1).get_int();
    unsigned num_constructors = datatype->get_parameter(o).get_int();
    if (c_idx >= num_constructors) {
        m_manager->raise_exception("invalid parameters for datatype operator");
        return 0;
    }
    unsigned k_i              = datatype->get_parameter(o + 1 + c_idx).get_int();

    switch (k) {
    case OP_DT_CONSTRUCTOR:
        if (num_parameters != 2) {
            m_manager->raise_exception("invalid parameters for datatype constructor");
            return 0;
        }
        else {


            symbol   c_name           = datatype->get_parameter(k_i).get_symbol();
            unsigned num_accessors    = datatype->get_parameter(k_i + 2).get_int();
            if (num_accessors != arity) {
                m_manager->raise_exception("invalid domain size for datatype constructor");
                return 0;
            }

            //
            // the reference count to domain could be 0.
            // we need to ensure that creating a temporary
            // copy of the same type causes a free.
            //
            sort_ref_vector domain_check(*m_manager);

            for (unsigned r = 0; r < num_accessors; r++) {
                sort_ref ty(*m_manager);
                ty = get_type(*m_manager, m_family_id, datatype, datatype->get_parameter(k_i + 4 + 2*r));
                domain_check.push_back(ty);
                if (ty != domain[r]) {
                    m_manager->raise_exception("invalid domain for datatype constructor");
                    return 0;
                }

            }
            func_decl_info info(m_family_id, k, num_parameters, parameters);
            info.m_private_parameters = true;
            SASSERT(info.private_parameters());
            return m_manager->mk_func_decl(c_name, arity, domain, datatype, info);
        }
    case OP_DT_RECOGNISER:
        if (num_parameters != 2 || arity != 1 || domain[0] != datatype) {
            m_manager->raise_exception("invalid parameters for datatype recogniser");
            return 0;
        }
        else {
            symbol   r_name = datatype->get_parameter(k_i + 1).get_symbol();
            sort *    b     = m_manager->mk_bool_sort();
            func_decl_info info(m_family_id, k, num_parameters, parameters);
            info.m_private_parameters = true;
            SASSERT(info.private_parameters());
            return m_manager->mk_func_decl(r_name, arity, domain, b, info);
        }
    case OP_DT_ACCESSOR:
        if (num_parameters != 3 || arity != 1 || domain[0] != datatype) {
            m_manager->raise_exception("invalid parameters for datatype accessor");
            return 0;
        }
        else {
            unsigned a_idx            = parameters[2].get_int();
            unsigned num_accessors    = datatype->get_parameter(k_i + 2).get_int();
            if (a_idx >= num_accessors) {
                m_manager->raise_exception("invalid datatype accessor");
                return 0;
            }
            symbol a_name         = datatype->get_parameter(k_i + 3 + 2*a_idx).get_symbol();
            sort * a_type         = get_type(*m_manager, m_family_id, datatype, datatype->get_parameter(k_i + 4 + 2*a_idx));
            func_decl_info info(m_family_id, k, num_parameters, parameters);
            info.m_private_parameters = true;
            SASSERT(info.private_parameters());
            return m_manager->mk_func_decl(a_name, arity, domain, a_type, info);
        }
        break;
    default:
        m_manager->raise_exception("invalid datatype operator kind");
        return 0;
    }
}