diff --git a/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.33.0__drop_token_account_id.sql b/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.33.0__drop_token_account_id.sql index 4d02ef3614c..c8bed544051 100644 --- a/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.33.0__drop_token_account_id.sql +++ b/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.33.0__drop_token_account_id.sql @@ -6,7 +6,7 @@ alter table if exists token_account drop constraint token_account_pkey; alter table if exists token_account - add primary key (created_timestamp); + add primary key (created_timestamp, token_id); alter table if exists token_account drop column if exists id; diff --git a/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.2__time_scale_index_init.sql b/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.2__time_scale_index_init.sql index 6f5285f827d..4d8d22900f9 100644 --- a/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.2__time_scale_index_init.sql +++ b/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.2__time_scale_index_init.sql @@ -103,7 +103,7 @@ create unique index if not exists token__id_timestamp -- token_account alter table token_account - add primary key (created_timestamp); + add primary key (created_timestamp, token_id); create unique index if not exists token_account__token_account_timestamp on token_account (token_id, account_id, created_timestamp); diff --git a/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.3__time_scale_compression.sql b/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.3__time_scale_compression.sql index 44e962fd001..89cbdb99681 100644 --- a/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.3__time_scale_compression.sql +++ b/hedera-mirror-importer/src/main/resources/db/migration/v2/V2.0.3__time_scale_compression.sql @@ -79,7 +79,7 @@ alter table token set (timescaledb.compress, timescaledb.compress_segmentby = 'token_id'); alter table token_account - set (timescaledb.compress, timescaledb.compress_segmentby = 'account_id'); + set (timescaledb.compress, timescaledb.compress_segmentby = 'token_id'); alter table token_balance set (timescaledb.compress, timescaledb.compress_segmentby = 'account_id, token_id'); diff --git a/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/parser/record/entity/sql/SqlEntityListenerTest.java b/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/parser/record/entity/sql/SqlEntityListenerTest.java index ba5f36d2d13..f51c2582bf9 100644 --- a/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/parser/record/entity/sql/SqlEntityListenerTest.java +++ b/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/parser/record/entity/sql/SqlEntityListenerTest.java @@ -47,6 +47,7 @@ import com.hedera.mirror.importer.domain.LiveHash; import com.hedera.mirror.importer.domain.NonFeeTransfer; import com.hedera.mirror.importer.domain.RecordFile; +import com.hedera.mirror.importer.domain.StreamFileData; import com.hedera.mirror.importer.domain.Token; import com.hedera.mirror.importer.domain.TokenAccount; import com.hedera.mirror.importer.domain.TokenFreezeStatusEnum; @@ -56,7 +57,6 @@ import com.hedera.mirror.importer.domain.Transaction; import com.hedera.mirror.importer.domain.TransactionTypeEnum; import com.hedera.mirror.importer.exception.MissingFileException; -import com.hedera.mirror.importer.domain.StreamFileData; import com.hedera.mirror.importer.repository.ContractResultRepository; import com.hedera.mirror.importer.repository.CryptoTransferRepository; import com.hedera.mirror.importer.repository.EntityRepository; @@ -240,7 +240,7 @@ void onEntityIdDuplicates() throws Exception { sqlEntityListener.onEntityId(entityId); // duplicate within file completeFileAndCommit(); - recordFile = insertRecordFileRecord(UUID.randomUUID().toString(), null, null, 1L); + recordFile = insertRecordFileRecord(UUID.randomUUID().toString(), null, null, 2L); sqlEntityListener.onStart(new StreamFileData(fileName, null)); sqlEntityListener.onEntityId(entityId); // duplicate across files completeFileAndCommit(); diff --git a/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/repository/TokenAccountRepositoryTest.java b/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/repository/TokenAccountRepositoryTest.java index 6b1d6eb8948..bb03a46f6c8 100644 --- a/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/repository/TokenAccountRepositoryTest.java +++ b/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/repository/TokenAccountRepositoryTest.java @@ -1,8 +1,6 @@ package com.hedera.mirror.importer.repository; -import java.util.Optional; import javax.annotation.Resource; -import org.apache.commons.codec.DecoderException; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -16,33 +14,55 @@ public class TokenAccountRepositoryTest extends AbstractRepositoryTest { @Resource protected TokenAccountRepository tokenAccountRepository; - private final EntityId tokenId = EntityId.of("0.0.101", EntityTypeEnum.TOKEN); - private final EntityId accountId = EntityId.of("0.0.102", EntityTypeEnum.ACCOUNT); + private final String tokenId = "0.0.101"; + private final String accountId = "0.0.102"; @Test - void save() throws DecoderException { - TokenAccount token = tokenAccountRepository.save(tokenAccount("0.0.101", "0.0.102", 1)); + void save() { + TokenAccount token = tokenAccountRepository.save(tokenAccount(tokenId, accountId, 1)); Assertions.assertThat(tokenAccountRepository.findById(token.getId()).get()) .isNotNull() .isEqualTo(token); } @Test - void findByTokenIdAndAccountId() throws DecoderException { - tokenAccountRepository.save(tokenAccount("0.0.101", "0.0.102", 1)); - String tokenId = "0.2.22"; - String accountId = "0.2.44"; - TokenAccount token2 = tokenAccountRepository.save(tokenAccount(tokenId, accountId, 2)); + void findByTokenIdAndAccountId() { + tokenAccountRepository.save(tokenAccount(tokenId, accountId, 1)); + String tokenId2 = "0.2.22"; + String accountId2 = "0.2.44"; + TokenAccount token2 = tokenAccountRepository.save(tokenAccount(tokenId2, accountId2, 2)); tokenAccountRepository.save(tokenAccount("1.0.7", "1.0.34", 3)); Assertions.assertThat(tokenAccountRepository - .findByTokenIdAndAccountId(EntityId.of(tokenId, EntityTypeEnum.TOKEN).getId(), EntityId - .of(accountId, EntityTypeEnum.ACCOUNT).getId()).get()) + .findByTokenIdAndAccountId(EntityId.of(tokenId2, EntityTypeEnum.TOKEN).getId(), EntityId + .of(accountId2, EntityTypeEnum.ACCOUNT).getId()).get()) .isNotNull() .isEqualTo(token2); Assertions.assertThat(tokenAccountRepository .findByTokenIdAndAccountId(EntityId.of("1.2.3", EntityTypeEnum.TOKEN).getId(), EntityId - .of("0.2.44", EntityTypeEnum.ACCOUNT).getId())).isEqualTo(Optional.empty()); + .of("0.2.44", EntityTypeEnum.ACCOUNT).getId())).isNotPresent(); + } + + @Test + void findByTokenIdAndAccountIdMultipleTokensSameAccount() { + String tokenId2 = "0.2.22"; + String accountId2 = "0.0.44"; + long createTimestamp1 = 55; + long createTimestamp2 = 66; + tokenAccountRepository.save(tokenAccount(tokenId, accountId, createTimestamp1)); + tokenAccountRepository + .save(tokenAccount(tokenId, accountId, createTimestamp2)); + TokenAccount tokenAccount_1_2 = tokenAccountRepository + .save(tokenAccount(tokenId2, accountId, createTimestamp2)); + Assertions.assertThat(tokenAccountRepository + .findByTokenIdAndAccountId(EntityId.of(tokenId2, EntityTypeEnum.TOKEN).getId(), EntityId + .of(accountId, EntityTypeEnum.ACCOUNT).getId()).get()) + .isNotNull() + .isEqualTo(tokenAccount_1_2); + + Assertions.assertThat(tokenAccountRepository + .findByTokenIdAndAccountId(EntityId.of(tokenId2, EntityTypeEnum.TOKEN).getId(), EntityId + .of(accountId2, EntityTypeEnum.ACCOUNT).getId())).isNotPresent(); } private TokenAccount tokenAccount(String tokenId, String accountId, long createdTimestamp) {