Skip to content

Commit

Permalink
use int instead of int32 in APIs
Browse files Browse the repository at this point in the history
Query/Scan.limit isn't bound by DynamoDB API limits, so it can exceed MaxInt32
Make scan segmentation > MaxInt32 an error
  • Loading branch information
guregu committed May 4, 2024
1 parent ec1651c commit 681c46a
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
)

go 1.20
go 1.21
15 changes: 9 additions & 6 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"math"
"strings"

"github.com/aws/aws-sdk-go-v2/service/dynamodb"
Expand All @@ -29,7 +30,7 @@ type Query struct {
projection string
filters []string
consistent bool
limit int32
limit int
searchLimit int32
order *Order

Expand Down Expand Up @@ -169,16 +170,17 @@ func (q *Query) Consistent(on bool) *Query {
}

// Limit specifies the maximum amount of results to return.
func (q *Query) Limit(limit int32) *Query {
func (q *Query) Limit(limit int) *Query {
q.limit = limit
return q
}

// SearchLimit specifies the maximum amount of results to examine.
// If a filter is not specified, the number of results will be limited.
// If a filter is specified, the number of results to consider for filtering will be limited.
func (q *Query) SearchLimit(limit int32) *Query {
q.searchLimit = limit
// Note: limit will be capped to MaxInt32 as that is the maximum number the DynamoDB API will accept.
func (q *Query) SearchLimit(limit int) *Query {
q.searchLimit = int32(min(limit, math.MaxInt32))
return q
}

Expand Down Expand Up @@ -307,7 +309,7 @@ type queryIter struct {
output *dynamodb.QueryOutput
err error
idx int
n int32
n int

// last item evaluated
last Item
Expand Down Expand Up @@ -498,7 +500,8 @@ func (q *Query) queryInput() *dynamodb.QueryInput {
}
if q.limit > 0 {
if len(q.filters) == 0 {
req.Limit = &q.limit
limit := int32(min(math.MaxInt32, q.limit))
req.Limit = &limit
}
}
if q.searchLimit > 0 {
Expand Down
9 changes: 7 additions & 2 deletions scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"math"
"strings"
"sync"

Expand Down Expand Up @@ -58,9 +59,13 @@ func (s *Scan) Index(name string) *Scan {
// Segment specifies the Segment and Total Segments to operate on in a manual parallel scan.
// This is useful if you want to control the parallel scans by yourself instead of using ParallelIter.
// Ignored by ParallelIter and friends.
// totalSegments must be less than MaxInt32 due to API limits.
func (s *Scan) Segment(segment int, totalSegments int) *Scan {
s.segment = int32(segment)
s.totalSegments = int32(totalSegments)
if totalSegments > math.MaxInt32 {
s.setError(fmt.Errorf("dynamo: total segments in Scan must be less than or equal to %d (got %d)", math.MaxInt32, totalSegments))
}
return s
}

Expand Down Expand Up @@ -126,7 +131,7 @@ func (s *Scan) Limit(limit int) *Scan {
// Use this along with StartFrom and Iter's LastEvaluatedKey to split up results.
// Note that DynamoDB limits result sets to 1MB.
func (s *Scan) SearchLimit(limit int) *Scan {
s.searchLimit = int32(limit)
s.searchLimit = int32(min(limit, math.MaxInt32))
return s
}

Expand Down Expand Up @@ -281,7 +286,7 @@ func (s *Scan) scanInput() *dynamodb.ScanInput {
}
if s.limit > 0 {
if len(s.filters) == 0 {
limit := int32(s.limit)
limit := int32(min(s.limit, math.MaxInt32))
input.Limit = &limit
}
}
Expand Down

0 comments on commit 681c46a

Please sign in to comment.