aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/float.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r--src/backend/utils/adt/float.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 4ee93ac04e1..c7c0b5842b1 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -2435,6 +2435,50 @@ check_float8_array(ArrayType *transarray, const char *caller, int n)
return (float8 *) ARR_DATA_PTR(transarray);
}
+/*
+ * float8_combine
+ *
+ * An aggregate combine function used to combine two 3 fields
+ * aggregate transition data into a single transition data.
+ * This function is used only in two stage aggregation and
+ * shouldn't be called outside aggregate context.
+ */
+Datum
+float8_combine(PG_FUNCTION_ARGS)
+{
+ ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
+ ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
+ float8 *transvalues1;
+ float8 *transvalues2;
+ float8 N,
+ sumX,
+ sumX2;
+
+ if (!AggCheckCallContext(fcinfo, NULL))
+ elog(ERROR, "aggregate function called in non-aggregate context");
+
+ transvalues1 = check_float8_array(transarray1, "float8_combine", 3);
+ N = transvalues1[0];
+ sumX = transvalues1[1];
+ sumX2 = transvalues1[2];
+
+ transvalues2 = check_float8_array(transarray2, "float8_combine", 3);
+
+ N += transvalues2[0];
+ sumX += transvalues2[1];
+ CHECKFLOATVAL(sumX, isinf(transvalues1[1]) || isinf(transvalues2[1]),
+ true);
+ sumX2 += transvalues2[2];
+ CHECKFLOATVAL(sumX2, isinf(transvalues1[2]) || isinf(transvalues2[2]),
+ true);
+
+ transvalues1[0] = N;
+ transvalues1[1] = sumX;
+ transvalues1[2] = sumX2;
+
+ PG_RETURN_ARRAYTYPE_P(transarray1);
+}
+
Datum
float8_accum(PG_FUNCTION_ARGS)
{
@@ -2762,6 +2806,69 @@ float8_regr_accum(PG_FUNCTION_ARGS)
}
}
+/*
+ * float8_regr_combine
+ *
+ * An aggregate combine function used to combine two 6 fields
+ * aggregate transition data into a single transition data.
+ * This function is used only in two stage aggregation and
+ * shouldn't be called outside aggregate context.
+ */
+Datum
+float8_regr_combine(PG_FUNCTION_ARGS)
+{
+ ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
+ ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
+ float8 *transvalues1;
+ float8 *transvalues2;
+ float8 N,
+ sumX,
+ sumX2,
+ sumY,
+ sumY2,
+ sumXY;
+
+ if (!AggCheckCallContext(fcinfo, NULL))
+ elog(ERROR, "aggregate function called in non-aggregate context");
+
+ transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 6);
+ N = transvalues1[0];
+ sumX = transvalues1[1];
+ sumX2 = transvalues1[2];
+ sumY = transvalues1[3];
+ sumY2 = transvalues1[4];
+ sumXY = transvalues1[5];
+
+ transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 6);
+
+ N += transvalues2[0];
+ sumX += transvalues2[1];
+ CHECKFLOATVAL(sumX, isinf(transvalues1[1]) || isinf(transvalues2[1]),
+ true);
+ sumX2 += transvalues2[2];
+ CHECKFLOATVAL(sumX2, isinf(transvalues1[2]) || isinf(transvalues2[2]),
+ true);
+ sumY += transvalues2[3];
+ CHECKFLOATVAL(sumY, isinf(transvalues1[3]) || isinf(transvalues2[3]),
+ true);
+ sumY2 += transvalues2[4];
+ CHECKFLOATVAL(sumY2, isinf(transvalues1[4]) || isinf(transvalues2[4]),
+ true);
+ sumXY += transvalues2[5];
+ CHECKFLOATVAL(sumXY, isinf(transvalues1[5]) || isinf(transvalues2[5]),
+ true);
+
+ transvalues1[0] = N;
+ transvalues1[1] = sumX;
+ transvalues1[2] = sumX2;
+ transvalues1[3] = sumY;
+ transvalues1[4] = sumY2;
+ transvalues1[5] = sumXY;
+
+ PG_RETURN_ARRAYTYPE_P(transarray1);
+}
+
+
Datum
float8_regr_sxx(PG_FUNCTION_ARGS)
{