Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spanner: row.ToStructLenient doesn't work for STRUCT data type #5938

Closed
yfuruyama opened this issue Apr 25, 2022 · 1 comment · Fixed by #5944
Closed

spanner: row.ToStructLenient doesn't work for STRUCT data type #5938

yfuruyama opened this issue Apr 25, 2022 · 1 comment · Fixed by #5944
Assignees
Labels
api: spanner Issues related to the Spanner API. priority: p2 Moderately-important priority. Fix may not be included in next release.

Comments

@yfuruyama
Copy link
Contributor

Client

Cloud Spanner

Environment

macOS

Go Environment

$ go version
go version go1.16 darwin/amd64

Code

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"

	"cloud.google.com/go/spanner"
)

type Result struct {
	C []*Inner `spanner:"C"`
}

type Inner struct {
	A int64 `spanner:"A"`
	//B int64 `spanner:"B"`
}

func main() {
	var projectID, instanceID, databaseID string

	flag.StringVar(&projectID, "project", "", "GCP Project ID")
	flag.StringVar(&instanceID, "instance", "", "Cloud Spanner Instance ID")
	flag.StringVar(&databaseID, "database", "", "Cloud Spanner Database ID")
	flag.Parse()

	if projectID == "" || instanceID == "" || databaseID == "" {
		flag.Usage()
		os.Exit(1)
	}

	dbPath := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, databaseID)
	ctx := context.Background()
	client, err := spanner.NewClient(ctx, dbPath)
	if err != nil {
		log.Fatalf("failed to create spanner client: %v", err)
	}
	defer client.Close()

	query := "SELECT ARRAY(SELECT STRUCT(1 AS A, 2 AS B)) AS C"
	if err := client.Single().Query(ctx, spanner.NewStatement(query)).Do(func(r *spanner.Row) error {
		var result Result
		return r.ToStructLenient(&result)
	}); err != nil {
		log.Fatalf("failed to run query: %v", err)
	}
}

Expected behavior

row.ToStructLenient should decode the row successfully.

Actual behavior

Got the following decoding error.

2022/04/25 23:45:10 failed to run query: spanner: code = "InvalidArgument", desc = "cannot decode field C of Cloud Spanner STRUCT fields:{name:\"C\" type:{code:ARRAY array_element_type:{code:STRUCT struct_type:{fields:{name:\"A\" type:{code:INT64}} fields:{name:\"B\" type:{code:INT64}}}}}}, cannot decode list_value:{values:{string_value:\"1\"} values:{string_value:\"2\"}}(array element 0) as STRUCT, Go struct &{A:1}(type *main.Inner) has no or duplicate fields for Cloud Spanner STRUCT field B"
exit status 1

Screenshots

N/A

Additional context

  • STRUCT type is used in Spanner system table as well (e.g. SAMPLE_LOCK_REQUESTS in lock-statistics), so it's preferable to allow users to use row.ToStructLenient to decode inner STRUCT type.
@yfuruyama yfuruyama added the triage me I really want to be triaged. label Apr 25, 2022
@product-auto-label product-auto-label bot added the api: spanner Issues related to the Spanner API. label Apr 25, 2022
@rahul2393 rahul2393 added priority: p2 Moderately-important priority. Fix may not be included in next release. and removed triage me I really want to be triaged. labels Apr 26, 2022
@rahul2393
Copy link
Contributor

Thanks @yfuruyama for opening the issue, I have created the PR to address this, please take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the Spanner API. priority: p2 Moderately-important priority. Fix may not be included in next release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants