/* * 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; }
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); }
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); }
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); }