cp sql/ from GNU Taler exchange

This commit is contained in:
swrup 2025-11-11 10:03:07 +01:00
parent 4749bb7c62
commit 11ee418801
132 changed files with 16912 additions and 0 deletions

View file

@ -0,0 +1,193 @@
--
-- 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 <http://www.gnu.org/licenses/>
--
---------------------------------------------------------------------------
-- Main DB setup loop
---------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION exchange_do_create_tables(
num_partitions INTEGER
-- NULL: no partitions, add foreign constraints
-- 0: no partitions, no foreign constraints
-- 1: only 1 default partition
-- > 1: normal partitions
)
RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLARE
tc CURSOR FOR
SELECT table_serial_id
,name
,action
,partitioned
,by_range
FROM exchange.exchange_tables
WHERE NOT finished
ORDER BY table_serial_id ASC;
BEGIN
FOR rec IN tc
LOOP
CASE rec.action
-- "create" actions apply to master and partitions, providing the partition ID to the creation function (if any)
WHEN 'create'
THEN
IF (rec.partitioned AND
(num_partitions IS NOT NULL))
THEN
-- Create master table with partitioning.
EXECUTE FORMAT(
'SELECT exchange.create_table_%s (%s)'::text
,rec.name
,quote_literal('0')
);
IF (rec.by_range OR
(num_partitions = 0))
THEN
-- Create default partition.
IF (rec.by_range)
THEN
-- Range partition
EXECUTE FORMAT(
'CREATE TABLE exchange.%s_default'
' PARTITION OF %s'
' DEFAULT'
,rec.name
,rec.name
);
ELSE
-- Hash partition
EXECUTE FORMAT(
'CREATE TABLE exchange.%s_default'
' PARTITION OF %s'
' FOR VALUES WITH (MODULUS 1, REMAINDER 0)'
,rec.name
,rec.name
);
END IF;
ELSE
FOR i IN 1..num_partitions LOOP
-- Create num_partitions
EXECUTE FORMAT(
'CREATE TABLE exchange.%I'
' PARTITION OF %I'
' FOR VALUES WITH (MODULUS %s, REMAINDER %s)'
,rec.name || '_' || i
,rec.name
,num_partitions
,i-1
);
END LOOP;
END IF;
ELSE
-- Only create master table. No partitions.
EXECUTE FORMAT(
'SELECT exchange.create_table_%s ()'::text
,rec.name
);
END IF;
EXECUTE FORMAT(
'DROP FUNCTION exchange.create_table_%s'::text
,rec.name
);
-- "alter" actions apply to master and partitions (but are called without partition ID, as altering master applies to partitions for these); use when changing table layouts (adding or removing columns).
WHEN 'alter'
THEN
-- Alter master table.
EXECUTE FORMAT(
'SELECT exchange.alter_table_%s ()'::text
,rec.name
);
EXECUTE FORMAT(
'DROP FUNCTION exchange.alter_table_%s'::text
,rec.name
);
-- Constrain action apply to master OR each partition (but not on master if we have partitions); use to create (or remove) indices or constraints that apply to a partition and may not be aligned with the partition key
WHEN 'constrain'
THEN
ASSERT rec.partitioned, 'constrain action only applies to partitioned tables';
IF (num_partitions IS NULL)
THEN
-- Constrain master table
EXECUTE FORMAT(
'SELECT exchange.constrain_table_%s (NULL)'::text
,rec.name
);
ELSE
IF ( (num_partitions = 0) OR
(rec.by_range) )
THEN
-- Constrain default table
EXECUTE FORMAT(
'SELECT exchange.constrain_table_%s (%s)'::text
,rec.name
,quote_literal('default')
);
ELSE
-- Constrain each partition
FOR i IN 1..num_partitions LOOP
EXECUTE FORMAT(
'SELECT exchange.constrain_table_%s (%s)'::text
,rec.name
,quote_literal(i)
);
END LOOP;
END IF;
END IF;
EXECUTE FORMAT(
'DROP FUNCTION exchange.constrain_table_%s'::text
,rec.name
);
-- Foreign actions only apply if partitioning is off; use for foreign-key constraints that may span partitions
WHEN 'foreign'
THEN
IF (num_partitions IS NULL)
THEN
-- Add foreign constraints
EXECUTE FORMAT(
'SELECT exchange.foreign_table_%s (%s)'::text
,rec.name
,NULL
);
END IF;
EXECUTE FORMAT(
'DROP FUNCTION exchange.foreign_table_%s'::text
,rec.name
);
-- "master" actions only apply to the master table
WHEN 'master'
THEN
EXECUTE FORMAT(
'SELECT exchange.master_table_%s ()'::text
,rec.name
);
EXECUTE FORMAT(
'DROP FUNCTION exchange.master_table_%s'::text
,rec.name
);
ELSE
ASSERT FALSE, 'unsupported action type: ' || rec.action;
END CASE; -- END CASE (rec.action)
-- Mark as finished
UPDATE exchange.exchange_tables
SET finished=TRUE
WHERE table_serial_id=rec.table_serial_id;
END LOOP; -- create/alter/drop actions
END $$;
COMMENT ON FUNCTION exchange_do_create_tables
IS 'Creates all tables for the given number of partitions that need creating. Does NOT support sharding.';