Рассчитать максимальное значение и сумму в то же время - PullRequest
0 голосов
/ 10 мая 2019

Для моего проекта я создаю некую обычную функцию фагрегата, которая используется для применения дифференциальной конфиденциальности. До сих пор я смог реализовать функции MAX и MIN, добавив немного шума Лапласа. У меня проблемы с агрегатом SUM_LAPLACE. Моя верхняя граница (чувствительность) должна быть абсолютной величиной значения MAX в столбце.

Как я могу одновременно вычислить максимум и сумму, а затем передать в функцию два выходных значения?

CREATE OR REPLACE FUNCTION calculateSum(real,real,OUT real, OUT real) AS $$
DECLARE 
   sumValue real := 0;
       max_v real;
BEGIN
   IF $1 IS NULL THEN
    sumValue := sumValue + $2;
   ELSIF $2 IS NULL THEN
    sumValue := sumValue + $1;
   ELSIF $2 IS NULL AND $1 IS NULL THEN
    sumValue := sumValue;
   ELSE
    sumValue := $1 + $2;
   END IF;
       max_v = searchmaximumvalue($1,$2);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION addLaplacianNoiseSum(real) RETURNS real AS $$
DECLARE
    epsilon real := 1.2;
    sensivity real := (epsilon * 2) + ($1/2);
    laplaceDistribution real;
 BEGIN
 laplaceDistribution := sensivity / (epsilon);
 RETURN  $1 + laplaceDistribution;

 END;
 $$ LANGUAGE plpgsql;

CREATE AGGREGATE SUM_LAPLACE(real)
(
SFUNC = calculateSum,
STYPE = real,
FINALFUNC = addLaplacianNoiseSum
);

Функция searchmaximumvalue ($ 1, $ 2) работает нормально. Я хотел бы вернуть из первой функции сумму и max_v и передать их второй функции ниже. Как я могу это сделать?

1 Ответ

1 голос
/ 10 мая 2019

demo: db <> fiddle

Вы можете создать свой собственный тип возврата:

CREATE TYPE my_type AS (sum real, max_v real);

Это может использоваться в SFUNC:

CREATE OR REPLACE FUNCTION calculateSum(my_type, real) RETURNS my_type  -- returns my_type
AS $$
DECLARE 
   sumValue real := 0;
   max_v real;
   output my_type; -- new variable of my_type
BEGIN
   /* A LOT OF CODE HERE */

   output.sum := sumValue;
   output.max_v := max_v;

   RETURN output;
END;
$$ LANGUAGE plpgsql;

И, конечно, в качестве входных данных для вашего FINALFUNC:

CREATE OR REPLACE FUNCTION addLaplacianNoiseSum(my_type) RETURNS real AS $$

Использование его в FINALFUNC:

$1.max_v
$1.sum

Тогда ваш агрегат будет выглядеть как

CREATE AGGREGATE SUM_LAPLACE(real) (
    SFUNC = calculateSum,
    STYPE = my_type,         -- return type == my_type
    FINALFUNC = addLaplacianNoiseSum
);
...