go-sql-spanner icon indicating copy to clipboard operation
go-sql-spanner copied to clipboard

Unable to scan into an array of struct

Open egonelbre opened this issue 1 year ago • 3 comments

Scanning array of spanner structs into a slice of Go structs doesn't seem to be working. Smallest reproducer:

func structTypes(projectId, instanceId, databaseId string) error {
	ctx := context.Background()
	db, err := sql.Open("spanner", fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectId, instanceId, databaseId))
	if err != nil {
		return fmt.Errorf("failed to open database connection: %v\n", err)
	}
	defer db.Close()

	type Entry struct {
		ID   int64
		Name string
	}

	entries := []Entry{
		{ID: 0, Name: "Hello"},
		{ID: 1, Name: "World"},
	}

	rows, err := db.QueryContext(ctx, "SELECT ARRAY(SELECT AS STRUCT * FROM UNNEST(@entries)) AS entries", entries)
	if err != nil {
		return fmt.Errorf("failed to execute query: %v", err)
	}
	defer rows.Close()

	for rows.Next() {
		var allEntries []Entry
		if err := rows.Scan(&allEntries); err != nil {
			return fmt.Errorf("failed to scan row values: %v", err)
		}
		fmt.Printf("%#v\n", allEntries)
	}
	if err := rows.Err(); err != nil {
		return fmt.Errorf("failed to execute query: %v", err)
	}
	return nil
}

This fails with:

2024/11/06 14:40:44 failed to scan row values: sql: Scan error on column index 0, name "entries": unsupported Scan, storing driver.Value type <nil> into type *[]main.Entry
exit status 1

If the code is changed to use TO_JSON and spanner.NullJSON it is able to return the correct values.

It's unclear whether the issue is in go-sql-spanner or upstream.

egonelbre avatar Nov 06 '24 12:11 egonelbre