merchant-0047.sql (2685B)
1 -- 2 -- This file is part of TALER 3 -- Copyright (C) 2026 Taler Systems SA 4 -- 5 -- TALER is free software; you can redistribute it and/or modify it under the 6 -- terms of the GNU General Public License as published by the Free Software 7 -- Foundation; either version 3, or (at your option) any later version. 8 -- 9 -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 -- A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 -- 13 -- You should have received a copy of the GNU General Public License along with 14 -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 -- 16 17 -- @file merchant-0047.sql 18 -- @brief Advance order sequences past retained contracts after migration 0036 19 -- 20 -- Run database upgrades with merchant writers stopped. This prevents further 21 -- serial reuse; it does not renumber orders already assigned low serials or 22 -- repair existing collisions. Historical listing order therefore stays as is. 23 24 BEGIN; 25 26 SELECT _v.register_patch('merchant-0047', NULL, NULL); 27 28 SET search_path TO merchant; 29 30 CREATE PROCEDURE merchant.merchant_0047_init(s TEXT) 31 LANGUAGE plpgsql 32 AS $OUTER$ 33 DECLARE 34 order_sequence REGCLASS; 35 current_next NUMERIC; 36 required_next NUMERIC; 37 max_serial INT8; 38 BEGIN 39 EXECUTE format('SET LOCAL search_path TO %I', s); 40 LOCK TABLE merchant_orders, merchant_contract_terms IN ACCESS EXCLUSIVE MODE; 41 42 order_sequence := pg_get_serial_sequence( 43 format('%I.merchant_orders', s), 'order_serial')::REGCLASS; 44 EXECUTE format( 45 'SELECT last_value::NUMERIC + CASE WHEN is_called THEN 1 ELSE 0 END FROM %s', 46 order_sequence) 47 INTO current_next; 48 SELECT GREATEST( 49 COALESCE((SELECT MAX(order_serial)::NUMERIC FROM merchant_orders), 0), 50 COALESCE((SELECT MAX(order_serial)::NUMERIC FROM merchant_contract_terms), 0)) + 1 51 INTO required_next; 52 SELECT seqmax INTO max_serial FROM pg_sequence WHERE seqrelid = order_sequence; 53 IF GREATEST(current_next, required_next) > max_serial THEN 54 RAISE EXCEPTION 'Order serial sequence exhausted for instance %', s; 55 END IF; 56 57 -- Unlike setval(), RESTART is rolled back if a later instance fixup fails. 58 -- Leave already-safe sequences alone, including their is_called state. 59 IF current_next < required_next THEN 60 EXECUTE format('ALTER SEQUENCE %s RESTART WITH %s', 61 order_sequence, required_next); 62 END IF; 63 64 SET LOCAL search_path TO merchant; 65 END 66 $OUTER$; 67 68 INSERT INTO merchant.instance_fixups 69 (migration_name, version) 70 VALUES ('merchant_0047_init', 47); 71 CALL merchant.fixup_instance_schema (47::INT8); 72 73 COMMIT;