I have a struct as follows
type MyEntity struct {
PF []byte `json:"-" datastore:"_pf"`
}
Querying without a Projection works fine. However, when I query with projection on "_pf" field, I get "type mismatch: string versus []uint8" error. I implemented the PropertyLoadSaver and examined the prop.Value for "_pf" property and found that some rows return []byte type and some return string. So, why is projected query failing with this error while non-projected queries are fine? At the moment I am resolving this by implementing PropertyLoadSaver interface and explicitly checking types and converting string type to []byte type to solve this problem.
Here is the complete test case. This is reproduced on cloud datastore emulator. Use appropriate value for datastoreProject variable below. Rest all should directly work. You can see the behavior by inserting both entities or one of the types of the entities. The error that is displayed is
panic: datastore: cannot load field "_pf" into a "tests.MyEntity": type mismatch: string versus []uint8 [recovered]
panic: datastore: cannot load field "_pf" into a "tests.MyEntity": type mismatch: string versus []uint8
Following is the code.
type MyEntity struct {
PF []byte `json:"-" datastore:"_pf"`
}
func TestPackedField(t *testing.T) {
e1 := &MyEntity{PF: []byte{83, 0, 0, 0, 93, 150, 154, 206, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3}} // returns []byte on projection
e2 := &MyEntity{PF: []byte{83, 0, 0, 0, 93, 120, 79, 87, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3}} // returns string on projection
ctx := context.Background()
conn, err := datastore.NewClient(ctx, datastoreProject)
if err != nil {
panic(err)
}
bkey := datastore.NameKey("Bytes", "bytearray", nil)
if true {
conn.Put(ctx, bkey, e1)
}
skey := datastore.NameKey("Bytes", "string", nil)
if true {
conn.Put(ctx, skey, e2)
}
q1 := datastore.NewQuery("Bytes").Order("-_pf").Limit(2)
var elfull []*MyEntity
if _, err := conn.GetAll(ctx, q1, &elfull); err != nil {
panic(err)
}
q2 := datastore.NewQuery("Bytes").Project("_pf").Order("-_pf").Limit(2)
var elprojected []*MyEntity
if _, err := conn.GetAll(ctx, q2, &elprojected); err != nil {
conn.Delete(ctx, bkey)
conn.Delete(ctx, skey)
panic(err)
}
}