diff options
author | Özgür Kesim <oec-taler@kesim.org> | 2023-07-27 23:57:07 +0200 |
---|---|---|
committer | Özgür Kesim <oec-taler@kesim.org> | 2023-07-27 23:57:07 +0200 |
commit | 571d43cef3732ed6f491d91a9e767a80008edeb1 (patch) | |
tree | b330d46d7698a07c4cc9c8baf1d2ee7793a4f02a /src/exchangedb/exchange-0001.sql | |
parent | 722e00b1e9869e0ff337d40b28f2ed71d8afcd76 (diff) |
[WiP] added TALER_AMOUNT type to Postgres - first in age_withdraw
- Added a type TALER_AMOUNT (val INT8, frac INT4) to Postgres.
- Added PLSQL functions/procedures
- amount_normalize(a)
- amount_add(a, b)
- amount_left_minus_right(l, r, diff, ok bool)
- Added PQ-helper functions
- TALER_PQ_query_param_amount_tuple()
- TALER_PQ_result_spec_amount_tuple()
- In table 'age_withdraw', changed fields 'amount_with_fee_val' and '..._frac'
into single field 'amount_with_fee' be of type TALER_AMOUNT
- Changed functions/stored procedures 'do_age_withdraw' and
'get_age_withdraw' to use new APIs.
=> make check runs through without errors,
age-withdraw and -reveal test passes.
Diffstat (limited to 'src/exchangedb/exchange-0001.sql')
-rw-r--r-- | src/exchangedb/exchange-0001.sql | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index d08aab4e..79a0dec1 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -137,6 +137,97 @@ COMMENT ON FUNCTION comment_partitioned_column IS 'Generic function to create a comment on column of a table that is partitioned.'; +-------------------------------------------------------------- +-- Taler amounts and helper functiosn +------------------------------------------------------------- + +DO $$ +BEGIN + CREATE TYPE TALER_AMOUNT + AS (val INT8 + ,frac INT4); + + COMMENT ON TYPE TALER_AMOUNT + IS 'Type to store a TALER-amount as (val, frac) pair.'; +EXCEPTION + WHEN duplicate_object THEN null; +END +$$; + +CREATE PROCEDURE amount_normalize( + IN amount TALER_AMOUNT + ,OUT normalized TALER_AMOUNT +) +LANGUAGE plpgsql +AS $$ +BEGIN + normalized.val = amount.val + amount.frac / 100000000; + normalized.frac = amount.frac % 100000000; +END $$; + +COMMENT ON PROCEDURE amount_normalize + IS 'Returns the normalized amount by adding to the .val the value of (.frac / 100000000) and removing the modulus 100000000 from .frac.'; + +CREATE PROCEDURE amount_add( + IN a TALER_AMOUNT + ,IN b TALER_AMOUNT + ,OUT sum TALER_AMOUNT +) +LANGUAGE plpgsql +AS $$ +BEGIN + sum = (a.val + b.val, a.frac + b.frac); + CALL amount_normalize(sum ,sum); + + IF (sum.val > (1<<52)) + THEN + RAISE EXCEPTION 'addition overflow'; + END IF; +END $$; + +COMMENT ON PROCEDURE amount_add + IS 'Returns the normalized sum of two amounts. It raises an exception when the resulting .val is larger than 2^52'; + +CREATE FUNCTION amount_left_minus_right( + IN l TALER_AMOUNT + ,IN r TALER_AMOUNT + ,OUT diff TALER_AMOUNT + ,OUT ok BOOLEAN +) +LANGUAGE plpgsql +AS $$ +BEGIN + +IF (l.val > r.val) +THEN + ok = TRUE; + IF (l.frac >= r.frac) + THEN + diff.val = l.val - r.val; + diff.frac = l.frac - r.frac; + ELSE + diff.val = l.val - r.val - 1; + diff.frac = l.frac + 100000000 - r.frac; + END IF; +ELSE + IF (l.val = r.val) AND (l.frac >= r.frac) + THEN + diff.val = 0; + diff.frac = l.frac - r.frac; + ok = TRUE; + ELSE + diff = (-1, -1); + ok = FALSE; + END IF; +END IF; + +RETURN; +END $$; + +COMMENT ON FUNCTION amount_left_minus_right + IS 'Subtracts the right amount from the left and returns the difference and TRUE, if the left amount is larger than the right, or an invalid amount and FALSE otherwise.'; + + --------------------------------------------------------------------------- -- Main DB setup loop --------------------------------------------------------------------------- |