Closed bancek closed 3 years ago
Amazon QLDB fails to insert a timestamp if fraction precision is 3 and milliseconds are divisible by 10.
3
10
Example:
type Entry struct { Time ion.Timestamp `ion:"time"` } millis := int64(1608218715340) t := time.Unix(0, millis*1000000) ts := ion.NewTimestampWithFractionalSeconds(t, ion.TimestampPrecisionNanosecond, ion.TimezoneUTC, 3) entry := Entry{ Time: ts, } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO Test ?", entry) })
The error from Amazon QLDB is
BadRequestException: Digests don't match { RespMetadata: { StatusCode: 400, RequestID: "3GH3JFguR5O3LLcAwTQiiN" }, Code_: "412", Message_: "Digests don't match" }
Is this an expected behavior?
I've fixed this with a helper to calculate the fraction precision but I would expect the ion-go library to do automatically.
ion-go
func getFractionPrecision(t time.Time) uint8 { millis := (t.UnixNano() / 1000000) % 1000 fractionPrecision := uint8(3) if millis == 0 { fractionPrecision = 0 } else { for millis > 0 && (millis%10) == 0 { millis /= 10 fractionPrecision-- } } return fractionPrecision }
This is also a problem when using time.Time in a struct and setting it to time.Now().UTC(). It fails with same error Digests don't match.
time.Time
struct
time.Now().UTC()
Digests don't match
Full example:
package main import ( "context" "time" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/qldbsession" "github.com/awslabs/amazon-qldb-driver-go/qldbdriver" ) func main() { awsSession := session.Must(session.NewSession(aws.NewConfig().WithRegion("us-east-1"))) qldbSession := qldbsession.New(awsSession) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background()) _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE Test") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) } type Entry struct { Time ion.Timestamp `ion:"time"` } millis := int64(1608218715340) t := time.Unix(0, millis*1000000) ts := ion.NewTimestampWithFractionalSeconds(t, ion.TimestampPrecisionNanosecond, ion.TimezoneUTC, 3) entry := Entry{ Time: ts, } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO Test ?", entry) }) if err != nil { panic(err) } }
Versions:
github.com/amzn/ion-go v1.1.0 github.com/amzn/ion-hash-go v1.1.0 github.com/aws/aws-sdk-go v1.36.8 github.com/awslabs/amazon-qldb-driver-go v1.0.1
Hi @bancek ,
We have released a new version of the Go driver that fixes this bug.
Thanks 🎉
Amazon QLDB fails to insert a timestamp if fraction precision is
3
and milliseconds are divisible by10
.Example:
The error from Amazon QLDB is
Is this an expected behavior?
I've fixed this with a helper to calculate the fraction precision but I would expect the
ion-go
library to do automatically.This is also a problem when using
time.Time
in astruct
and setting it totime.Now().UTC()
. It fails with same errorDigests don't match
.Full example:
Versions: