Repository: genjidb/genji (go)

Issue:
Unable to decode byte array
<!-- Please answer these questions before submitting your issue. Thanks! -->

### What version of Genji are you using?

```go
	github.com/genjidb/genji v0.8.1-0.20201027130408-3de6bdeb29e3
```

### Does this issue reproduce with the latest release?

I think it should reproduce, because responsible code is unaffected.

### What did you do?

```go
package main

import (
	"fmt"

	"github.com/genjidb/genji"
	"github.com/genjidb/genji/document"
)

func main() {
	db, err := genji.Open(":memory:")
	if err != nil {
		panic(err)
	}

	defer db.Close()

	err = db.Exec("CREATE TABLE foo")
	if err != nil {
		panic(err)
	}

	array := [4]uint8{1, 2, 3, 4}

	err = db.Exec("INSERT INTO foo (bar) VALUES (?)", &array)
	if err != nil {
		panic(err)
	}

	doc, err := db.QueryDocument("SELECT bar FROM foo")
	if err != nil {
		panic(err)
	}

	var dst [4]uint8
	err = document.Scan(doc, &dst)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%v\n", dst)

}
```

### What did you expect to see?

```sh
[1 2 3 4]
```

### What did you see instead?

```sh
panic: unsupported type reflect.Value. Invalid type

goroutine 1 [running]:
main.main()
	/home/dio/junk/genji_tests/main.go:38 +0x374
```

### What Go version and environment are you using?

<pre>
$ go version
go version go1.15.2 linux/amd64
</pre>

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/dio/.cache/go-build"
GOENV="/home/dio/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/dio/go/pkg/mod"
GOOS="linux"
GOPATH="/home/dio/go"
GOPRIVATE="gitlab.etecs.ru"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/dio/junk/genji_tests/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build716115602=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### Little research

It seems that genji has code for encoding arrays as specific case in switch (document/create.go:240), but deconding is lacking something.

If we look at document/scan.go:337 we can found case that it intended to handle slices. Code seems to be able to work with array more or less. So I tried to add case `reflect.Array` to it:

```go
	case reflect.Slice, reflect.Array:
```

But now flow fall in following if-branch:

```go
		if ref.Type().Elem().Kind() != reflect.Uint8 {
```

If we delete this branch, then genji will be able to work correctly with array (and possible will not be able to work with slices)

Pull request:
Fix blob to byte array decoding
Fixes #305 

Patch:
diff --git a/document/scan.go b/document/scan.go
index 27525e6f..e7187666 100644
--- a/document/scan.go
+++ b/document/scan.go
@@ -347,6 +347,20 @@ func scanValue(v Value, ref reflect.Value) error {
 			return err
 		}
 
+		return sliceScan(v.V.(Array), ref.Addr())
+	case reflect.Array:
+		if ref.Type().Elem().Kind() == reflect.Uint8 {
+			if v.Type != TextValue && v.Type != BlobValue {
+				return fmt.Errorf("cannot scan value of type %s to byte slice", v.Type)
+			}
+			reflect.Copy(ref, reflect.ValueOf(v.V))
+			return nil
+		}
+		v, err := v.CastAsArray()
+		if err != nil {
+			return err
+		}
+
 		return sliceScan(v.V.(Array), ref.Addr())
 	case reflect.Map:
 		v, err := v.CastAsDocument()


Test patch:
diff --git a/document/scan_test.go b/document/scan_test.go
index 4485e6a7..aa175de8 100644
--- a/document/scan_test.go
+++ b/document/scan_test.go
@@ -100,7 +100,14 @@ func TestScan(t *testing.T) {
 					Add("foo", document.NewTextValue("c")).
 					Add("bar", document.NewTextValue("d")),
 			),
-		)))
+		))).
+		Add("w", document.NewArrayValue(document.NewValueBuffer(
+			document.NewIntegerValue(1),
+			document.NewIntegerValue(2),
+			document.NewIntegerValue(3),
+			document.NewIntegerValue(4),
+		))).
+		Add("x", document.NewBlobValue([]byte{1, 2, 3, 4}))
 
 	type foo struct {
 		Foo string
@@ -128,8 +135,10 @@ func TestScan(t *testing.T) {
 	var s []*bool
 	var u []foo
 	var v []*foo
+	var w [4]int
+	var x [4]uint8
 
-	err = document.Scan(doc, &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o, &p, &r, &s, &u, &v)
+	err = document.Scan(doc, &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o, &p, &r, &s, &u, &v, &w, &x)
 	require.NoError(t, err)
 	require.Equal(t, a, []byte("foo"))
 	require.Equal(t, b, "bar")
@@ -160,6 +169,8 @@ func TestScan(t *testing.T) {
 	require.Equal(t, foo{Foo: "foo", Pub: strPtr("bar")}, k)
 	require.Equal(t, []foo{{Foo: "a", Pub: strPtr("b")}, {Foo: "c", Pub: strPtr("d")}}, u)
 	require.Equal(t, []*foo{{Foo: "a", Pub: strPtr("b")}, {Foo: "c", Pub: strPtr("d")}}, v)
+	require.Equal(t, [4]int{1, 2, 3, 4}, w)
+	require.Equal(t, [4]uint8{1, 2, 3, 4}, x)
 
 	t.Run("DocumentScanner", func(t *testing.T) {
 		var ds documentScanner
@@ -175,14 +186,14 @@ func TestScan(t *testing.T) {
 		m := make(map[string]interface{})
 		err := document.MapScan(doc, m)
 		require.NoError(t, err)
-		require.Len(t, m, 20)
+		require.Len(t, m, 22)
 	})
 
 	t.Run("MapPtr", func(t *testing.T) {
 		var m map[string]interface{}
 		err := document.MapScan(doc, &m)
 		require.NoError(t, err)
-		require.Len(t, m, 20)
+		require.Len(t, m, 22)
 	})
 
 	t.Run("Small Slice", func(t *testing.T) {