fix(eventstore): use decimal for position (#9881)

# Which Problems Are Solved

Float64 which was used for the event.Position field is [not precise in
go and gets rounded](https://github.com/golang/go/issues/47300). This
can lead to unprecies position tracking of events and therefore
projections especially on cockcoachdb as the position used there is a
big number.

example of a unprecies position:
exact: 1725257931223002628
float64: 1725257931223002624.000000

# How the Problems Are Solved

The float64 was replaced by
[github.com/jackc/pgx-shopspring-decimal](https://github.com/jackc/pgx-shopspring-decimal).

# Additional Changes

Rename `latestSequence`-queries to `latestPosition`

# Additional Context

closes https://github.com/zitadel/zitadel/issues/8863
This commit is contained in:
Silvan
2025-05-14 12:14:08 +02:00
committed by GitHub
parent 5331841675
commit dafde7468d
47 changed files with 338 additions and 236 deletions

View File

@@ -3,6 +3,8 @@ package repository
import (
"database/sql"
"github.com/shopspring/decimal"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/zerrors"
@@ -55,6 +57,8 @@ const (
//OperationNotIn checks if a stored value does not match one of the passed value list
OperationNotIn
OperationGreaterOrEquals
operationCount
)
@@ -233,10 +237,10 @@ func instanceIDsFilter(builder *eventstore.SearchQueryBuilder, query *SearchQuer
}
func positionAfterFilter(builder *eventstore.SearchQueryBuilder, query *SearchQuery) *Filter {
if builder.GetPositionAfter() == 0 {
if builder.GetPositionAtLeast().IsZero() {
return nil
}
query.Position = NewFilter(FieldPosition, builder.GetPositionAfter(), OperationGreater)
query.Position = NewFilter(FieldPosition, builder.GetPositionAtLeast(), OperationGreaterOrEquals)
return query.Position
}
@@ -278,7 +282,7 @@ func eventDataFilter(query *eventstore.SearchQuery) *Filter {
}
func eventPositionAfterFilter(query *eventstore.SearchQuery) *Filter {
if pos := query.GetPositionAfter(); pos != 0 {
if pos := query.GetPositionAfter(); !pos.Equal(decimal.Decimal{}) {
return NewFilter(FieldPosition, pos, OperationGreater)
}
return nil