Агрегатная функция Postgres возвращает неправильное значение, функция перехода состояния в порядке - PullRequest
1 голос
/ 25 июня 2019

Я создал агрегатную функцию в postgresql, которая не возвращает ожидаемый результат, даже когда функция перехода работает, как ожидалось.Это определения:

-- State: _hil overrides non hil

CREATE TYPE conversion_state AS (
  source text,
  source_hil text,
  ai text,
  ai_hil text,
  expert text
);
-- final state function:
-- if coalesced source is repair -> false
-- if expert is replace -> false
-- if coalesced ai is reapir -> true
CREATE OR REPLACE FUNCTION conversion_final(conversion conversion_state)
 RETURNS boolean
 LANGUAGE plpgsql
AS $function$
DECLARE
  source text;
  ai_hil text;
BEGIN
    source = COALESCE(conversion.source_hil, conversion.source);
    IF source = 'REPAIR' THEN RETURN false; END IF;
    IF conversion.expert = 'REPLACE' THEN RETURN false; END IF;
    ai_hil := COALESCE(conversion.ai_hil, conversion.ai);
    RETURN ai_hil = 'REPAIR';
END;
$function$;

Эта функция работает, как и ожидалось.

CREATE OR REPLACE FUNCTION conversion_state_transition(
  state conversion_state, stage enum_assessments_stage, assess text
) RETURNS organizer.rr_conversion_state
LANGUAGE plpgsql
AS $function$
DECLARE
  r conversion_state;
BEGIN
    IF stage = 'source'
    THEN
        SELECT assess , state.source_hil, state.ai, state.ai_hil, state.expert INTO r.source, r.source_hil, r.ai, r.ai_hil, r.expert;
    END IF;
    IF stage = 'source_hil'
    THEN
        SELECT state.source, assess, state.ai, state.ai_hil, state.expert INTO r.source, r.source_hil, r.ai, r.ai_hil, r.expert;
    END IF;
    IF stage = 'ai'
    THEN
        SELECT state.source, state.source_hil, assess, state.ai_hil, state.expert INTO r.source, r.source_hil, r.ai, r.ai_hil, r.expert;
    END IF;
    IF stage = 'ai_hil'
    THEN
        SELECT state.source, state.source_hil, state.ai, assess, state.expert INTO r.source, r.source_hil, r.ai, r.ai_hil, r.expert;
    END IF;
    IF stage = 'expert'
    THEN
        SELECT state.source, state.source_hil, state.ai, state.ai_hil, assess INTO  r.source, r.source_hil, r.ai, r.ai_hil, r.expert;
    END IF;
    RETURN r;
END;
$function$;

Функция перехода состояния также работает, как и ожидалось, заполняя соответствующее поле состояния оценкой на основена этапе значение.

Теперь определение и использование агрегатной функции тривиально:

-- Aggregate function. Use it to convert (stage, assessment_string) into conversion when assessments are group by (id, area)
CREATE AGGREGATE conversion_a(enum_assessments_stage, text)(
    SFUNC=conversion_state_transition,
    FINALFUNC=conversion_final,
    STYPE=conversion_state,
    INITCOND='(NULL, NULL, NULL, NULL, NULL)'
);


CREATE OR REPLACE VIEW conversion AS
  SELECT assessments.id,
         assessments.area,
         conversion_a(assessments.stage, assessments.assessment_string) AS conversion
  FROM assessments
  WHERE assessments.type = 'REPAIR_REPLACE'
  GROUP BY assessments.id, assessments.area;

Когда я проверяю результаты этого представления, я получаю неправильные результаты.Есть идеи о том, что может происходить?С одной стороны, я подозреваю, что группировка может повлиять на результаты, но я не знаю, как это исправить.

...