From 416e8601bff8fcfae7adaa55c990f8c5ffbf68a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net>
Date: Wed, 19 Oct 2016 10:26:13 -0500
Subject: [PATCH] Don't use statements that are marked as dead.

---
 internal/sqladapter/database.go  |  6 ++++--
 internal/sqladapter/statement.go | 15 ++++++++++-----
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/internal/sqladapter/database.go b/internal/sqladapter/database.go
index 9d7370fd..7c1fa4d0 100644
--- a/internal/sqladapter/database.go
+++ b/internal/sqladapter/database.go
@@ -359,8 +359,10 @@ func (d *database) prepareStatement(stmt *exql.Statement) (*Stmt, string, error)
 	pc, ok := d.cachedStatements.ReadRaw(stmt)
 	if ok {
 		// The statement was cached.
-		ps := pc.(*Stmt).Open()
-		return ps, ps.query, nil
+		ps, err := pc.(*Stmt).Open()
+		if err == nil {
+			return ps, ps.query, nil
+		}
 	}
 
 	// Plain SQL query.
diff --git a/internal/sqladapter/statement.go b/internal/sqladapter/statement.go
index 0a8a4482..a57a3aed 100644
--- a/internal/sqladapter/statement.go
+++ b/internal/sqladapter/statement.go
@@ -2,6 +2,7 @@ package sqladapter
 
 import (
 	"database/sql"
+	"errors"
 	"sync/atomic"
 )
 
@@ -39,19 +40,23 @@ func NewStatement(stmt *sql.Stmt, query string) *Stmt {
 }
 
 // Open marks the statement as in-use
-func (c *Stmt) Open() *Stmt {
+func (c *Stmt) Open() (*Stmt, error) {
+	if atomic.LoadInt32(&c.dead) > 0 {
+		return nil, errors.New("statement is dead")
+	}
 	atomic.AddInt64(&c.count, 1)
-	return c
+	return c, nil
 }
 
 // Close closes the underlying statement if no other go-routine is using it.
 func (c *Stmt) Close() {
 	if atomic.AddInt64(&c.count, -1) > 0 {
-		// There are another goroutines using this statement so we don't want to
-		// close it for real.
+		// If this counter is more than 0 then there are other goroutines using
+		// this statement so we don't want to close it for real.
 		return
 	}
-	if atomic.LoadInt32(&c.dead) > 0 {
+
+	if atomic.LoadInt32(&c.dead) > 0 && atomic.LoadInt64(&c.count) <= 0 {
 		// Statement is dead and we can close it for real.
 		c.Stmt.Close()
 		// Reduce active statements counter.
-- 
GitLab