stmtcache.go (1922B)
1 // Package stmtcache is a cache for statement descriptions. 2 package stmtcache 3 4 import ( 5 "strconv" 6 "sync/atomic" 7 8 "github.com/jackc/pgx/v5/pgconn" 9 ) 10 11 var stmtCounter int64 12 13 // NextStatementName returns a statement name that will be unique for the lifetime of the program. 14 func NextStatementName() string { 15 n := atomic.AddInt64(&stmtCounter, 1) 16 return "stmtcache_" + strconv.FormatInt(n, 10) 17 } 18 19 // Cache caches statement descriptions. 20 type Cache interface { 21 // Get returns the statement description for sql. Returns nil if not found. 22 Get(sql string) *pgconn.StatementDescription 23 24 // Put stores sd in the cache. Put panics if sd.SQL is "". Put does nothing if sd.SQL already exists in the cache. 25 Put(sd *pgconn.StatementDescription) 26 27 // Invalidate invalidates statement description identified by sql. Does nothing if not found. 28 Invalidate(sql string) 29 30 // InvalidateAll invalidates all statement descriptions. 31 InvalidateAll() 32 33 // HandleInvalidated returns a slice of all statement descriptions invalidated since the last call to HandleInvalidated. 34 HandleInvalidated() []*pgconn.StatementDescription 35 36 // Len returns the number of cached prepared statement descriptions. 37 Len() int 38 39 // Cap returns the maximum number of cached prepared statement descriptions. 40 Cap() int 41 } 42 43 func IsStatementInvalid(err error) bool { 44 pgErr, ok := err.(*pgconn.PgError) 45 if !ok { 46 return false 47 } 48 49 // https://github.com/jackc/pgx/issues/1162 50 // 51 // We used to look for the message "cached plan must not change result type". However, that message can be localized. 52 // Unfortunately, error code "0A000" - "FEATURE NOT SUPPORTED" is used for many different errors and the only way to 53 // tell the difference is by the message. But all that happens is we clear a statement that we otherwise wouldn't 54 // have so it should be safe. 55 possibleInvalidCachedPlanError := pgErr.Code == "0A000" 56 return possibleInvalidCachedPlanError 57 }