Skip to content

Commit

Permalink
Improved type casting in the appender (#196)
Browse files Browse the repository at this point in the history
* initial commit

* remove appender from vector functions

* more appender removal

* new vector.go file

* support missing timestamp types

* implicit types init commit

* fix typo

* formatting

* better type casting

* small fixes

* renamed vector.go to appender_vector.go

---------

Co-authored-by: Marc Boeker
  • Loading branch information
taniabogatsch authored Apr 5, 2024
1 parent d928f8c commit f5dc5c3
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 149 deletions.
12 changes: 5 additions & 7 deletions appender.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import "C"

import (
"database/sql/driver"
"reflect"
"unsafe"
)

Expand Down Expand Up @@ -187,18 +186,17 @@ func (a *Appender) newDataChunk(colCount int) {
}

func (a *Appender) appendRowSlice(args []driver.Value) error {
for i, v := range args {
for i, val := range args {
vec := a.vectors[i]
if v == nil {
vec.setNull(a.currSize)
continue
}

// Ensure that the types match before attempting to append anything.
if err := vec.typeMatch(reflect.TypeOf(v)); err != nil {
v, err := vec.tryCast(val)
if err != nil {
// Use 1-based indexing for readability, as we're talking about columns.
return columnError(err, i+1)
}

// Append the row to the data chunk.
vec.fn(&vec, a.currSize, v)
}

Expand Down
38 changes: 38 additions & 0 deletions appender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"database/sql/driver"
"encoding/json"
"fmt"
"math/rand"
"testing"
Expand Down Expand Up @@ -761,3 +762,40 @@ func TestAppenderUint8SliceTinyInt(t *testing.T) {
require.NoError(t, res.Close())
cleanupAppender(t, c, con, a)
}

func TestAppenderWithJSON(t *testing.T) {
c, con, a := prepareAppender(t, `
CREATE TABLE test (
id DOUBLE,
l DOUBLE[],
s STRUCT(a DOUBLE, b VARCHAR)
)`)

jsonBytes := []byte(`{"id": 42, "l":[1, 2, 3], "s":{"a":101, "b":"hello"}}`)
var jsonData map[string]interface{}
err := json.Unmarshal(jsonBytes, &jsonData)
require.NoError(t, err)

require.NoError(t, a.AppendRow(jsonData["id"], jsonData["l"], jsonData["s"]))
require.NoError(t, a.Flush())

// Verify results.
res, err := sql.OpenDB(c).QueryContext(context.Background(), `SELECT * FROM test`)
require.NoError(t, err)

for res.Next() {
var (
id uint64
l interface{}
s interface{}
)
err := res.Scan(&id, &l, &s)
require.NoError(t, err)
require.Equal(t, uint64(42), id)
require.Equal(t, "[1 2 3]", fmt.Sprint(l))
require.Equal(t, "map[a:101 b:hello]", fmt.Sprint(s))
}

require.NoError(t, res.Close())
cleanupAppender(t, c, con, a)
}
Loading

0 comments on commit f5dc5c3

Please sign in to comment.