diff --git a/api-server/api-server-common/src/storage/impls/postgres/queries.rs b/api-server/api-server-common/src/storage/impls/postgres/queries.rs index 1247279429..e4bea055a7 100644 --- a/api-server/api-server-common/src/storage/impls/postgres/queries.rs +++ b/api-server/api-server-common/src/storage/impls/postgres/queries.rs @@ -2527,15 +2527,15 @@ impl<'a, 'b> QueryFromConnection<'a, 'b> { .query( r#" WITH count_tokens AS ( - SELECT count(token_id) FROM ml.fungible_token + SELECT count(DISTINCT token_id) FROM ml.fungible_token ) - (SELECT token_id + (SELECT DISTINCT token_id FROM ml.fungible_token ORDER BY token_id OFFSET $1 LIMIT $2) UNION ALL - (SELECT nft_id + (SELECT DISTINCT nft_id FROM ml.nft_issuance ORDER BY nft_id OFFSET GREATEST($1 - (SELECT * FROM count_tokens), 0) @@ -2572,16 +2572,16 @@ impl<'a, 'b> QueryFromConnection<'a, 'b> { .query( r#" WITH count_tokens AS ( - SELECT count(token_id) FROM ml.fungible_token WHERE ticker ILIKE $3 + SELECT count(DISTINCT token_id) FROM ml.fungible_token WHERE ticker ILIKE $3 ) - (SELECT token_id + (SELECT DISTINCT token_id FROM ml.fungible_token WHERE ticker ILIKE $3 ORDER BY token_id OFFSET $1 LIMIT $2) UNION ALL - (SELECT nft_id + (SELECT DISTINCT nft_id FROM ml.nft_issuance WHERE ticker ILIKE $3 ORDER BY nft_id diff --git a/api-server/storage-test-suite/src/basic.rs b/api-server/storage-test-suite/src/basic.rs index 664b813a8a..b31c1badf9 100644 --- a/api-server/storage-test-suite/src/basic.rs +++ b/api-server/storage-test-suite/src/basic.rs @@ -14,7 +14,10 @@ // limitations under the License. use serialization::extras::non_empty_vec::DataOrNoVec; -use std::{collections::BTreeMap, sync::Arc}; +use std::{ + collections::{BTreeMap, BTreeSet}, + sync::Arc, +}; use crate::helpers::make_trial; use crate::make_test; @@ -1858,6 +1861,33 @@ where let ids = db_tx.get_token_ids_by_ticker(6, 0, &format!("A{c}")).await.unwrap(); assert!(ids.is_empty()); } + + // Fungible token data is stored per block height, so a token that gets updated has + // a row for every height it changed at. It must still be listed only once. + db_tx + .set_fungible_token_issuance( + random_token_id1, + block_height.next_height(), + token_data.clone(), + ) + .await + .unwrap(); + + let ids = db_tx.get_token_ids(6, 0).await.unwrap(); + let unique_ids: BTreeSet<_> = ids.iter().collect(); + assert_eq!( + ids.len(), + unique_ids.len(), + "get_token_ids returned duplicates" + ); + + let ids = db_tx.get_token_ids_by_ticker(6, 0, &token_ticker).await.unwrap(); + let unique_ids: BTreeSet<_> = ids.iter().collect(); + assert_eq!( + ids.len(), + unique_ids.len(), + "get_token_ids_by_ticker returned duplicates" + ); } // test coin and token statistics