Exemple #1
0
/*
 * PLyNumber_ToJsonbValue(PyObject *obj)
 *
 * Transform python number to JsonbValue.
 */
static JsonbValue *
PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum)
{
	Numeric		num;
	char	   *str = PLyObject_AsString(obj);

	PG_TRY();
	{
		Datum		numd;

		numd = DirectFunctionCall3(numeric_in,
								   CStringGetDatum(str),
								   ObjectIdGetDatum(InvalidOid),
								   Int32GetDatum(-1));
		num = DatumGetNumeric(numd);
	}
	PG_CATCH();
	{
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 (errmsg("could not convert value \"%s\" to jsonb", str))));
	}
	PG_END_TRY();

	pfree(str);

	/*
	 * jsonb doesn't allow NaN (per JSON specification), so we have to prevent
	 * it here explicitly.  (Infinity is also not allowed in jsonb, but
	 * numeric_in above already catches that.)
	 */
	if (numeric_is_nan(num))
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 (errmsg("cannot convert NaN to jsonb"))));

	jbvNum->type = jbvNumeric;
	jbvNum->val.numeric = num;

	return jbvNum;
}
Exemple #2
0
Datum
pgstrom_numeric_avg_final(PG_FUNCTION_ARGS)
{
	numeric_agg_state *state;
	Datum		vN;
	Datum		result;

	state = PG_ARGISNULL(0) ? NULL : (numeric_agg_state *)PG_GETARG_POINTER(0);

	/* If there were no non-null inputs, return NULL */
	if (state == NULL || state->N == 0)
		PG_RETURN_NULL();
	/* If any NaN value is accumlated, return NaN */
	if (numeric_is_nan(DatumGetNumeric(state->sumX)))
		PG_RETURN_NUMERIC(state->sumX);

	vN = DirectFunctionCall1(int8_numeric, Int64GetDatum(state->N));
	result = DirectFunctionCall2(numeric_div, state->sumX, vN);

	PG_RETURN_NUMERIC(result);
}
Exemple #3
0
Datum
jsonb_bool(PG_FUNCTION_ARGS)
{
	Jsonb	   *j = PG_GETARG_JSONB(0);

	if (JB_ROOT_IS_SCALAR(j))
	{
		JsonbValue *jv;

		jv = getIthJsonbValueFromContainer(&j->root, 0);
		switch (jv->type)
		{
			case jbvNull:
				PG_RETURN_NULL();
			case jbvString:
				PG_RETURN_BOOL(jv->val.string.len > 0);
			case jbvNumeric:
				{
					Datum		b;

					if (numeric_is_nan(jv->val.numeric))
						PG_RETURN_BOOL(false);

					b = DirectFunctionCall2(numeric_ne,
											NumericGetDatum(jv->val.numeric),
											get_numeric_0_datum());
					PG_RETURN_DATUM(b);
				}
			case jbvBool:
				PG_RETURN_BOOL(jv->val.boolean);
			default:
				elog(ERROR, "unknown jsonb scalar type");
		}
	}

	Assert(JB_ROOT_IS_OBJECT(j) || JB_ROOT_IS_ARRAY(j));
	PG_RETURN_BOOL(JB_ROOT_COUNT(j) > 0);
}
Exemple #4
0
static Numeric
pgstrom_numeric_stddev_internal(numeric_agg_state *state,
								bool variance, bool sample)
{
	Datum	vZero;
	Datum	vN;
	Datum	vN2;
	Datum	vSumX;
	Datum	vSumX2;
	Datum	result;

	if (state == NULL)
		return NULL;
	/* NaN checks */
	if (numeric_is_nan(DatumGetNumeric(state->sumX)))
		return DatumGetNumeric(state->sumX);
	if (numeric_is_nan(DatumGetNumeric(state->sumX2)))
		return DatumGetNumeric(state->sumX2);

	/*
	 * Sample stddev and variance are undefined when N <= 1; population stddev
	 * is undefined when N == 0. Return NULL in either case.
	 */
	if (sample ? state->N <= 1 : state->N <= 0)
		return NULL;

	/* const_zero = (Numeric)0 */
	vZero  = DirectFunctionCall3(numeric_in,
								 CStringGetDatum("0"),
								 ObjectIdGetDatum(0),
								 Int32GetDatum(-1));
	/* vN = (Numeric)N */
	vN = DirectFunctionCall1(int8_numeric, Int64GetDatum(state->N));
	/* vsumX = sumX * sumX */
	vSumX = DirectFunctionCall2(numeric_mul, state->sumX, state->sumX);
	/* vsumX2 = N * sumX2 */
	vSumX2 = DirectFunctionCall2(numeric_mul, state->sumX2, vN);
	/* N * sumX2 - sumX * sumX */
	vSumX2 = DirectFunctionCall2(numeric_sub, vSumX2, vSumX);

	/* Watch out for roundoff error producing a negative numerator */
	if (DirectFunctionCall2(numeric_cmp, vSumX2, vZero) <= 0)
		return DatumGetNumeric(vZero);

	if (!sample)
		vN2 = DirectFunctionCall2(numeric_mul, vN, vN);	/* N * N */
	else
	{
		Datum	vOne;
		Datum	vNminus;

		vOne = DirectFunctionCall3(numeric_in,
								   CStringGetDatum("1"),
								   ObjectIdGetDatum(0),
								   Int32GetDatum(-1));
		vNminus = DirectFunctionCall2(numeric_sub, vN, vOne);
		vN2 = DirectFunctionCall2(numeric_mul, vN, vNminus); /* N * (N - 1) */
	}
	/* variance */
	result = DirectFunctionCall2(numeric_div, vSumX2, vN2);
	/* stddev? */
	if (!variance)
		result = DirectFunctionCall1(numeric_sqrt, result);

	return DatumGetNumeric(result);
}
Datum
gbt_numeric_penalty(PG_FUNCTION_ARGS)
{
	GISTENTRY  *o = (GISTENTRY *) PG_GETARG_POINTER(0);
	GISTENTRY  *n = (GISTENTRY *) PG_GETARG_POINTER(1);
	float	   *result = (float *) PG_GETARG_POINTER(2);

	Numeric		us,
				os,
				ds;

	GBT_VARKEY *org = (GBT_VARKEY *) DatumGetPointer(o->key);
	GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
	Datum		uni;
	GBT_VARKEY_R rk,
				ok,
				uk;

	rk = gbt_var_key_readable(org);
	uni = PointerGetDatum(gbt_var_key_copy(&rk, TRUE));
	gbt_var_bin_union(&uni, newe, &tinfo);
	ok = gbt_var_key_readable(org);
	uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));

	us = DatumGetNumeric(DirectFunctionCall2(
											 numeric_sub,
											 PointerGetDatum(uk.upper),
											 PointerGetDatum(uk.lower)
											 ));

	os = DatumGetNumeric(DirectFunctionCall2(
											 numeric_sub,
											 PointerGetDatum(ok.upper),
											 PointerGetDatum(ok.lower)
											 ));

	ds = DatumGetNumeric(DirectFunctionCall2(
											 numeric_sub,
											 NumericGetDatum(us),
											 NumericGetDatum(os)
											 ));

	if (numeric_is_nan(us))
	{
		if (numeric_is_nan(os))
			*result = 0.0;
		else
			*result = 1.0;
	}
	else
	{
		Numeric		nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0)));

		*result = 0.0;

		if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul)))
		{
			*result += FLT_MIN;
			os = DatumGetNumeric(DirectFunctionCall2(
													 numeric_div,
													 NumericGetDatum(ds),
													 NumericGetDatum(us)
													 ));
			*result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os)));
		}
	}

	if (*result > 0)
		*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));

	PG_RETURN_POINTER(result);
}