浏览代码

Correctly unmarshal null UDT responses

When a UDT column is null it's data will be empty, when this is the
case set the unmarshal target to its zero value if possible and
return.
Chris Bannister 10 年之前
父节点
当前提交
08c272cd69
共有 2 个文件被更改,包括 62 次插入1 次删除
  1. 8 1
      marshal.go
  2. 54 0
      udt_test.go

+ 8 - 1
marshal.go

@@ -1381,8 +1381,15 @@ func unmarshalUDT(info TypeInfo, data []byte, value interface{}) error {
 		}
 		}
 	}
 	}
 
 
-	udt := info.(UDTTypeInfo)
+	if len(data) == 0 {
+		if k.CanSet() {
+			k.Set(reflect.Zero(k.Type()))
+		}
+
+		return nil
+	}
 
 
+	udt := info.(UDTTypeInfo)
 	for _, e := range udt.Elements {
 	for _, e := range udt.Elements {
 		size := readInt(data[:4])
 		size := readInt(data[:4])
 		data = data[4:]
 		data = data[4:]

+ 54 - 0
udt_test.go

@@ -187,3 +187,57 @@ func TestUDT_Proto2error(t *testing.T) {
 		t.Fatalf("expected to get %v got %v", ErrorUDTUnavailable, err)
 		t.Fatalf("expected to get %v got %v", ErrorUDTUnavailable, err)
 	}
 	}
 }
 }
+
+func TestUDT_NullObject(t *testing.T) {
+	if *flagProto < protoVersion3 {
+		t.Skip("UDT are only available on protocol >= 3")
+	}
+
+	session := createSession(t)
+	defer session.Close()
+
+	err := createTable(session, `CREATE TYPE udt_null_type(
+		name text,
+		owner text);`)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = createTable(session, `CREATE TABLE udt_null_table(
+		id uuid,
+		udt_col frozen<udt_null_type>,
+
+		primary key(id)
+	);`)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	type col struct {
+		Name  string `cql:"name"`
+		Owner string `cql:"owner"`
+	}
+
+	id := TimeUUID()
+	err = session.Query("INSERT INTO udt_null_table(id) VALUES(?)", id).Exec()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	readCol := &col{
+		Name:  "temp",
+		Owner: "temp",
+	}
+
+	err = session.Query("SELECT udt_col FROM udt_null_table WHERE id = ?", id).Scan(readCol)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if readCol.Name != "" {
+		t.Errorf("expected empty string to be returned for null udt: got %q", readCol.Name)
+	}
+	if readCol.Owner != "" {
+		t.Errorf("expected empty string to be returned for null udt: got %q", readCol.Owner)
+	}
+}