From 66b8b8a8e05f44b80b7482111b7dc7b2ccb4b93c Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Thu, 29 Oct 2026 00:06:52 +0400 Subject: [PATCH] =?UTF-8?q?perf(sql):=20=5Fform=5Faffected=5Frows=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B1=D0=B8=D1=80=D0=B0=D0=B5=D1=82=20=D1=82=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BA=D0=BE=20=D0=B7=D0=B0=D1=82=D1=80=D0=BE=D0=BD=D1=83?= =?UTF-8?q?=D1=82=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B2=D0=BE=20(AURORA-1850)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../sql/0051_upd_form_cells_subtree.sql | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/api/alembic/versions/sql/0051_upd_form_cells_subtree.sql b/api/alembic/versions/sql/0051_upd_form_cells_subtree.sql index 9bdc175..5f8befe 100644 --- a/api/alembic/versions/sql/0051_upd_form_cells_subtree.sql +++ b/api/alembic/versions/sql/0051_upd_form_cells_subtree.sql @@ -2626,3 +2626,117 @@ BEGIN END; $function$ ; + +CREATE OR REPLACE FUNCTION v3._form_affected_rows(p_form_id integer, p_sheet character varying, p_ids integer[], p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql + STABLE +AS $function$ +DECLARE + v_form_type VARCHAR; + v_strip TEXT[] := ARRAY[]::TEXT[]; + v_lc_path INT[]; + v_eid_set INT[]; + v_ei_path INT[]; +BEGIN + SELECT bf.form_type_code INTO v_form_type + FROM v3.budget_form bf + WHERE bf.id = p_form_id; + + IF p_sections IS NOT NULL THEN + SELECT COALESCE(array_agg(k), ARRAY[]::TEXT[]) + INTO v_strip + FROM unnest(ARRAY['plan','seq_dfip','seq_ssp','approved','contract','booking', + 'contract_summary','allocation','collegial','ckk', + 'sequestration','reserve','contract_detail', + 'q1','q2','q3','q4','totals', + 'fact_q1','fact_q2','fact_q3','fact_q4']) AS k + WHERE NOT (k = ANY(p_sections)); + END IF; + + IF v_form_type = 'FORM_1' AND p_sheet IN ('AHR','CAP','OPER') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form1_view(p_form_id, p_sheet, p_sections, p_direction, COALESCE(p_ids, '{}'::INT[])) v + ORDER BY v.sort_order; + RETURN; + ELSIF v_form_type = 'FORM_2' AND p_sheet IN ('AHR','CAP','OPER','AHR_RENT','AHR_UTILITY','AHR_SECURITY','AHR_LIMIT','OTCH9F') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form2_view(p_form_id, p_sheet, p_sections, COALESCE(p_ids, '{}'::INT[])) v + ORDER BY v.sort_order; + RETURN; + END IF; + + IF p_sheet IN ('AHR_RENT','AHR_UTILITY','AHR_SECURITY') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE v.row_type = 'INPUT' AND (v.data->>'id')::INT = ANY(p_ids) + ORDER BY v.sort_order; + + ELSIF p_sheet = 'AHR_LIMIT' THEN + v_lc_path := v3._limit_template_path_set(p_ids); + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE (v.data->>'id')::INT = ANY(v_lc_path) + ORDER BY v.sort_order; + + ELSIF p_sheet = 'OTCH9F' THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE EXISTS ( + SELECT 1 FROM v3.fixed_asset_report far + WHERE far.id = ANY(p_ids) + AND far.expense_item_id = (v.data->>'expense_item_id')::INT + AND far.equipment_name IS NOT DISTINCT FROM (v.data->>'equipment_name')) + ORDER BY v.sort_order; + + ELSE + SELECT array_agg(DISTINCT bl.expense_item_id) + INTO v_eid_set + FROM v3.budget_line bl + WHERE bl.id = ANY(p_ids); + v_ei_path := v3._expense_item_path_set(v_eid_set); + + IF v_form_type = 'FORM_4' THEN + RETURN QUERY + WITH vv AS MATERIALIZED ( + SELECT f.row_type, f.depth, f.sort_order, f.data + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) f + WHERE f.row_type <> 'META' + ), + chg AS ( + SELECT DISTINCT (x.data->'header'->>'program_id')::INT AS program_id, + (x.data->'header'->>'project_id')::INT AS project_id + FROM vv x + WHERE x.row_type = 'INPUT' AND (x.data->>'line_id')::INT = ANY(p_ids) + ) + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM vv v + WHERE (v.row_type = 'INPUT' AND (v.data->>'line_id')::INT = ANY(p_ids)) + OR (v.row_type = 'ROOT' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) + OR (v.row_type = 'GROUP' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) + AND (v.data->'header'->>'program_id')::INT IN (SELECT c.program_id FROM chg c)) + OR (v.row_type = 'ITEM' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) + AND (v.data->'header'->>'project_id')::INT IN (SELECT c.project_id FROM chg c)) + ORDER BY v.sort_order; + ELSE + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM') + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) + OR (v.row_type = 'INPUT' + AND (v.data->>'line_id')::INT = ANY(p_ids)) + ORDER BY v.sort_order; + END IF; + END IF; +END; +$function$ +;