[
https://issues.apache.org/jira/browse/IGNITE-18497?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Alexander Lapin updated IGNITE-18497:
-------------------------------------
Description:
*Motivation*
Indexes store all value associated with different versions of one entry. By the
reason, for getting value by primary index, we scan the index with the specific
key. If we insert, delete and again insert an entry with the same indexed
fields, the entry can resolve in versioned storage for different row ids. But
only one resolution should return not empty value, because only one entry can
exist by the unique index.
*Implementation notes*
The resolution happens here:
{code:java}
PartitionReplicaListener#resolveRowByPk(BinaryRow, HybridTimestamp){code}
But in case when a read result is resolved to null, need to continue the loop,
because the actual value associated with the key may be removed (this is the
null value, but it is not actual) and inserted again.
h3. upd 1:
# Seems that it's rather simple in case of primary index (and given ticket is
about primary index) because keys are unmodifiable, so it's only possible to
have multiple entries for particular search key only in case of creation->
removal -> creation. That means that we can have one and only one non empty
readResult for any read timestamp for the given key. As a result, as Vlad told
we should continue the iteration over index rowIds if(readResult.isEmpty())
# We should probably fix PartitionReplicaListener#resolveReadResult instead of
returning null in case of null readResult we should complete future with null.
{code:java}
private CompletableFuture<BinaryRow> resolveReadResult(
ReadResult readResult,
@Nullable UUID txId,
@Nullable HybridTimestamp timestamp,
@Nullable Supplier<BinaryRow> lastCommitted
) {
if (readResult == null) {
return null;
{code}
was:
*Motivation*
Indexes store all value associated with different versions of one entry. By the
reason, for getting value by primary index, we scan the index with the specific
key. If we insert, delete and again insert an entry with the same indexed
fields, the entry can resolve in versioned storage for different row ids. But
only one resolution should return not empty value, because only one entry can
exist by the unique index.
*Implementation notes*
The resolution happens here:
{code:java}
PartitionReplicaListener#resolveRowByPk(BinaryRow, HybridTimestamp){code}
But in case when a read result is resolved to null, need to continue the loop,
because the actual value associated with the key may be removed (this is the
null value, but it is not actual) and inserted again.
h3. upd 1:
# As Vlad told we should continue the iteration over index rowIds
if(readResult.isEmpty())
# We should probably fix PartitionReplicaListener#resolveReadResult instead of
returning null in case of null readResult we should complete future with null.
{code:java}
private CompletableFuture<BinaryRow> resolveReadResult(
ReadResult readResult,
@Nullable UUID txId,
@Nullable HybridTimestamp timestamp,
@Nullable Supplier<BinaryRow> lastCommitted
) {
if (readResult == null) {
return null;
{code}
> Read only get returns a first one value getting from primary index
> ------------------------------------------------------------------
>
> Key: IGNITE-18497
> URL: https://issues.apache.org/jira/browse/IGNITE-18497
> Project: Ignite
> Issue Type: Bug
> Reporter: Vladislav Pyatkov
> Priority: Major
> Labels: ignite-3
>
> *Motivation*
> Indexes store all value associated with different versions of one entry. By
> the reason, for getting value by primary index, we scan the index with the
> specific key. If we insert, delete and again insert an entry with the same
> indexed fields, the entry can resolve in versioned storage for different row
> ids. But only one resolution should return not empty value, because only one
> entry can exist by the unique index.
> *Implementation notes*
> The resolution happens here:
> {code:java}
> PartitionReplicaListener#resolveRowByPk(BinaryRow, HybridTimestamp){code}
> But in case when a read result is resolved to null, need to continue the
> loop, because the actual value associated with the key may be removed (this
> is the null value, but it is not actual) and inserted again.
>
> h3. upd 1:
> # Seems that it's rather simple in case of primary index (and given ticket
> is about primary index) because keys are unmodifiable, so it's only possible
> to have multiple entries for particular search key only in case of creation->
> removal -> creation. That means that we can have one and only one non empty
> readResult for any read timestamp for the given key. As a result, as Vlad
> told we should continue the iteration over index rowIds
> if(readResult.isEmpty())
> # We should probably fix PartitionReplicaListener#resolveReadResult instead
> of returning null in case of null readResult we should complete future with
> null.
> {code:java}
> private CompletableFuture<BinaryRow> resolveReadResult(
> ReadResult readResult,
> @Nullable UUID txId,
> @Nullable HybridTimestamp timestamp,
> @Nullable Supplier<BinaryRow> lastCommitted
> ) {
> if (readResult == null) {
> return null;
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)