-- -- This file is part of TALER -- Copyright (C) 2014--2022 Taler Systems SA -- -- TALER is free software; you can redistribute it and/or modify it under the -- terms of the GNU General Public License as published by the Free Software -- Foundation; either version 3, or (at your option) any later version. -- -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -- A PARTICULAR PURPOSE. See the GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License along with -- TALER; see the file COPYING. If not, see -- CREATE OR REPLACE FUNCTION exchange_do_batch4_known_coin( IN in_coin_pub1 BYTEA, IN in_denom_pub_hash1 BYTEA, IN in_h_age_commitment1 BYTEA, IN in_denom_sig1 BYTEA, IN in_coin_pub2 BYTEA, IN in_denom_pub_hash2 BYTEA, IN in_h_age_commitment2 BYTEA, IN in_denom_sig2 BYTEA, IN in_coin_pub3 BYTEA, IN in_denom_pub_hash3 BYTEA, IN in_h_age_commitment3 BYTEA, IN in_denom_sig3 BYTEA, IN in_coin_pub4 BYTEA, IN in_denom_pub_hash4 BYTEA, IN in_h_age_commitment4 BYTEA, IN in_denom_sig4 BYTEA, OUT existed1 BOOLEAN, OUT existed2 BOOLEAN, OUT existed3 BOOLEAN, OUT existed4 BOOLEAN, OUT known_coin_id1 INT8, OUT known_coin_id2 INT8, OUT known_coin_id3 INT8, OUT known_coin_id4 INT8, OUT denom_pub_hash1 BYTEA, OUT denom_pub_hash2 BYTEA, OUT denom_pub_hash3 BYTEA, OUT denom_pub_hash4 BYTEA, OUT age_commitment_hash1 BYTEA, OUT age_commitment_hash2 BYTEA, OUT age_commitment_hash3 BYTEA, OUT age_commitment_hash4 BYTEA) LANGUAGE plpgsql AS $$ BEGIN WITH dd AS ( SELECT denominations_serial, coin FROM denominations WHERE denom_pub_hash IN (in_denom_pub_hash1, in_denom_pub_hash2, in_denom_pub_hash3, in_denom_pub_hash4) ),--dd input_rows AS ( VALUES (in_coin_pub1, in_denom_pub_hash1, in_h_age_commitment1, in_denom_sig1), (in_coin_pub2, in_denom_pub_hash2, in_h_age_commitment2, in_denom_sig2), (in_coin_pub3, in_denom_pub_hash3, in_h_age_commitment3, in_denom_sig3), (in_coin_pub4, in_denom_pub_hash4, in_h_age_commitment4, in_denom_sig4) ),--ir ins AS ( INSERT INTO known_coins ( coin_pub, denominations_serial, age_commitment_hash, denom_sig, remaining ) SELECT ir.coin_pub, dd.denominations_serial, ir.age_commitment_hash, ir.denom_sig, dd.coin FROM input_rows ir JOIN dd ON dd.denom_pub_hash = ir.denom_pub_hash ON CONFLICT DO NOTHING RETURNING known_coin_id ),--kc exists AS ( SELECT CASE WHEN ins.known_coin_id IS NOT NULL THEN FALSE ELSE TRUE END AS existed, ins.known_coin_id, dd.denom_pub_hash, kc.age_commitment_hash FROM input_rows ir LEFT JOIN ins ON ins.coin_pub = ir.coin_pub LEFT JOIN known_coins kc ON kc.coin_pub = ir.coin_pub LEFT JOIN dd ON dd.denom_pub_hash = ir.denom_pub_hash )--exists SELECT exists.existed AS existed1, exists.known_coin_id AS known_coin_id1, exists.denom_pub_hash AS denom_pub_hash1, exists.age_commitment_hash AS age_commitment_hash1, ( SELECT exists.existed FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 ) AS existed2, ( SELECT exists.known_coin_id FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 ) AS known_coin_id2, ( SELECT exists.denom_pub_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 ) AS denom_pub_hash2, ( SELECT exists.age_commitment_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 )AS age_commitment_hash2, ( SELECT exists.existed FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash3 ) AS existed3, ( SELECT exists.known_coin_id FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash3 ) AS known_coin_id3, ( SELECT exists.denom_pub_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash3 ) AS denom_pub_hash3, ( SELECT exists.age_commitment_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash3 )AS age_commitment_hash3, ( SELECT exists.existed FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash4 ) AS existed4, ( SELECT exists.known_coin_id FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash4 ) AS known_coin_id4, ( SELECT exists.denom_pub_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash4 ) AS denom_pub_hash4, ( SELECT exists.age_commitment_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash4 )AS age_commitment_hash4 FROM exists; RETURN; END $$; CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin( IN in_coin_pub1 BYTEA, IN in_denom_pub_hash1 BYTEA, IN in_h_age_commitment1 BYTEA, IN in_denom_sig1 BYTEA, IN in_coin_pub2 BYTEA, IN in_denom_pub_hash2 BYTEA, IN in_h_age_commitment2 BYTEA, IN in_denom_sig2 BYTEA, OUT existed1 BOOLEAN, OUT existed2 BOOLEAN, OUT known_coin_id1 INT8, OUT known_coin_id2 INT8, OUT denom_pub_hash1 BYTEA, OUT denom_pub_hash2 BYTEA, OUT age_commitment_hash1 BYTEA, OUT age_commitment_hash2 BYTEA) LANGUAGE plpgsql AS $$ BEGIN WITH dd AS ( SELECT denominations_serial, coin FROM denominations WHERE denom_pub_hash IN (in_denom_pub_hash1, in_denom_pub_hash2) ),--dd input_rows AS ( VALUES (in_coin_pub1, in_denom_pub_hash1, in_h_age_commitment1, in_denom_sig1), (in_coin_pub2, in_denom_pub_hash2, in_h_age_commitment2, in_denom_sig2) ),--ir ins AS ( INSERT INTO known_coins ( coin_pub, denominations_serial, age_commitment_hash, denom_sig, remaining ) SELECT ir.coin_pub, dd.denominations_serial, ir.age_commitment_hash, ir.denom_sig, dd.coin FROM input_rows ir JOIN dd ON dd.denom_pub_hash = ir.denom_pub_hash ON CONFLICT DO NOTHING RETURNING known_coin_id ),--kc exists AS ( SELECT CASE WHEN ins.known_coin_id IS NOT NULL THEN FALSE ELSE TRUE END AS existed, ins.known_coin_id, dd.denom_pub_hash, kc.age_commitment_hash FROM input_rows ir LEFT JOIN ins ON ins.coin_pub = ir.coin_pub LEFT JOIN known_coins kc ON kc.coin_pub = ir.coin_pub LEFT JOIN dd ON dd.denom_pub_hash = ir.denom_pub_hash )--exists SELECT exists.existed AS existed1, exists.known_coin_id AS known_coin_id1, exists.denom_pub_hash AS denom_pub_hash1, exists.age_commitment_hash AS age_commitment_hash1, ( SELECT exists.existed FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 ) AS existed2, ( SELECT exists.known_coin_id FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 ) AS known_coin_id2, ( SELECT exists.denom_pub_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 ) AS denom_pub_hash2, ( SELECT exists.age_commitment_hash FROM exists WHERE exists.denom_pub_hash = in_denom_pub_hash2 )AS age_commitment_hash2 FROM exists; RETURN; END $$; CREATE OR REPLACE FUNCTION exchange_do_batch1_known_coin( IN in_coin_pub1 BYTEA, IN in_denom_pub_hash1 BYTEA, IN in_h_age_commitment1 BYTEA, IN in_denom_sig1 BYTEA, OUT existed1 BOOLEAN, OUT known_coin_id1 INT8, OUT denom_pub_hash1 BYTEA, OUT age_commitment_hash1 BYTEA) LANGUAGE plpgsql AS $$ BEGIN WITH dd AS ( SELECT denominations_serial, coin FROM denominations WHERE denom_pub_hash IN (in_denom_pub_hash1, in_denom_pub_hash2) ),--dd input_rows AS ( VALUES (in_coin_pub1, in_denom_pub_hash1, in_h_age_commitment1, in_denom_sig1) ),--ir ins AS ( INSERT INTO known_coins ( coin_pub, denominations_serial, age_commitment_hash, denom_sig, remaining ) SELECT ir.coin_pub, dd.denominations_serial, ir.age_commitment_hash, ir.denom_sig, dd.coin FROM input_rows ir JOIN dd ON dd.denom_pub_hash = ir.denom_pub_hash ON CONFLICT DO NOTHING RETURNING known_coin_id ),--kc exists AS ( SELECT CASE WHEN ins.known_coin_id IS NOT NULL THEN FALSE ELSE TRUE END AS existed, ins.known_coin_id, dd.denom_pub_hash, kc.age_commitment_hash FROM input_rows ir LEFT JOIN ins ON ins.coin_pub = ir.coin_pub LEFT JOIN known_coins kc ON kc.coin_pub = ir.coin_pub LEFT JOIN dd ON dd.denom_pub_hash = ir.denom_pub_hash )--exists SELECT exists.existed AS existed1, exists.known_coin_id AS known_coin_id1, exists.denom_pub_hash AS denom_pub_hash1, exists.age_commitment_hash AS age_commitment_hash1 FROM exists; RETURN; END $$; /*** Experiment using a loop ***/ /* CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin( IN in_coin_pub1 BYTEA, IN in_denom_pub_hash1 TEXT, IN in_h_age_commitment1 TEXT, IN in_denom_sig1 TEXT, IN in_coin_pub2 BYTEA, IN in_denom_pub_hash2 TEXT, IN in_h_age_commitment2 TEXT, IN in_denom_sig2 TEXT, OUT existed1 BOOLEAN, OUT existed2 BOOLEAN, OUT known_coin_id1 INT8, OUT known_coin_id2 INT8, OUT denom_pub_hash1 TEXT, OUT denom_pub_hash2 TEXT, OUT age_commitment_hash1 TEXT, OUT age_commitment_hash2 TEXT) LANGUAGE plpgsql AS $$ DECLARE ins_values RECORD; BEGIN FOR i IN 1..2 LOOP ins_values := ( SELECT in_coin_pub1 AS coin_pub, in_denom_pub_hash1 AS denom_pub_hash, in_h_age_commitment1 AS age_commitment_hash, in_denom_sig1 AS denom_sig WHERE i = 1 UNION SELECT in_coin_pub2 AS coin_pub, in_denom_pub_hash2 AS denom_pub_hash, in_h_age_commitment2 AS age_commitment_hash, in_denom_sig2 AS denom_sig WHERE i = 2 ); WITH dd (denominations_serial, coin) AS ( SELECT denominations_serial, coin FROM denominations WHERE denom_pub_hash = ins_values.denom_pub_hash ), input_rows(coin_pub) AS ( VALUES (ins_values.coin_pub) ), ins AS ( INSERT INTO known_coins ( coin_pub, denominations_serial, age_commitment_hash, denom_sig, remaining ) SELECT input_rows.coin_pub, dd.denominations_serial, ins_values.age_commitment_hash, ins_values.denom_sig, coin FROM dd CROSS JOIN input_rows ON CONFLICT DO NOTHING RETURNING known_coin_id, denom_pub_hash ) SELECT CASE i WHEN 1 THEN COALESCE(ins.known_coin_id, 0) <> 0 AS existed1, ins.known_coin_id AS known_coin_id1, ins.denom_pub_hash AS denom_pub_hash1, ins.age_commitment_hash AS age_commitment_hash1 WHEN 2 THEN COALESCE(ins.known_coin_id, 0) <> 0 AS existed2, ins.known_coin_id AS known_coin_id2, ins.denom_pub_hash AS denom_pub_hash2, ins.age_commitment_hash AS age_commitment_hash2 END FROM ins; END LOOP; END; $$;*/