Explorar el Código

Fix bug fetching out unset timestamp values.

If your row exists but has an empty timestamp column, your time.Time
bind variable was being initialized to epoch time 0. Now it returns
early and does not modify the bind variable. I considered having it
instead set the bind variable to the go zero time.Time value, but
since that is techincally a legitimate time value as well it still
doesn't solve the semipredicate problem.

I tweaked the timestamp marshal code to do "val.UnixNano() / 1000000"
instead of "val.UnixNano() / time.Millisecond" because it doesn't make
sense to do operations directly between integers and time.Duration values.
The latter only works because the base unit for time.Duration happens to
be nanoseconds.
Muir Manders hace 11 años
padre
commit
803daed9cc
Se han modificado 2 ficheros con 29 adiciones y 1 borrados
  1. 25 0
      cassandra_test.go
  2. 4 1
      marshal.go

+ 25 - 0
cassandra_test.go

@@ -19,6 +19,7 @@ import (
 	"testing"
 	"time"
 	"unicode"
+
 	"speter.net/go/exp/math/dec/inf"
 )
 
@@ -1442,3 +1443,27 @@ func TestNilInQuery(t *testing.T) {
 		t.Fatalf("expected id to be 1, got %v", id)
 	}
 }
+
+// Don't initialize time.Time bind variable if cassandra timestamp column is empty
+func TestEmptyTimestamp(t *testing.T) {
+	session := createSession(t)
+	defer session.Close()
+
+	if err := createTable(session, "CREATE TABLE test_empty_timestamp (id int, time timestamp, num int, PRIMARY KEY (id))"); err != nil {
+		t.Fatalf("failed to create table with error '%v'", err)
+	}
+
+	if err := session.Query("INSERT INTO test_empty_timestamp (id, num) VALUES (?,?)", 1, 561).Exec(); err != nil {
+		t.Fatalf("failed to insert with err: %v", err)
+	}
+
+	var timeVal time.Time
+
+	if err := session.Query("SELECT time FROM test_empty_timestamp where id = ?", 1).Scan(&timeVal); err != nil {
+		t.Fatalf("failed to select with err: %v", err)
+	}
+
+	if !timeVal.IsZero() {
+		t.Errorf("time.Time bind variable should still be empty (was %s)", timeVal)
+	}
+}

+ 4 - 1
marshal.go

@@ -752,7 +752,7 @@ func marshalTimestamp(info *TypeInfo, value interface{}) ([]byte, error) {
 	case int64:
 		return encBigInt(v), nil
 	case time.Time:
-		x := v.In(time.UTC).UnixNano() / int64(time.Millisecond)
+		x := v.UnixNano() / int64(1000000)
 		return encBigInt(x), nil
 	}
 	rv := reflect.ValueOf(value)
@@ -773,6 +773,9 @@ func unmarshalTimestamp(info *TypeInfo, data []byte, value interface{}) error {
 		*v = decBigInt(data)
 		return nil
 	case *time.Time:
+		if len(data) == 0 {
+			return nil
+		}
 		x := decBigInt(data)
 		sec := x / 1000
 		nsec := (x - sec*1000) * 1000000