Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions csv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ func TestExperimentalCsvBehavior(t *testing.T) {
if err := writeCsvFromResultSet(&bytes.Buffer{}, nil); err == nil {
t.Fatal("writeCsvFromResultSet(nil) expected error")
}
if err := prepareCsvRowType(svwriter.NewCSVWriter(&bytes.Buffer{}), nil); err == nil {
w, err := svwriter.NewCSVWriter(&bytes.Buffer{})
if err != nil {
t.Fatalf("NewCSVWriter() error = %v", err)
}
if err := prepareCsvRowType(w, nil); err == nil {
t.Fatal("prepareCsvRowType(nil metadata) expected error")
}
})
Expand Down Expand Up @@ -139,7 +143,10 @@ func TestExperimentalCsvDumpFixtures(t *testing.T) {

// experimentalCsvViaSpanvalueWriter is the reference path for ResultSet-shaped fixtures.
func experimentalCsvViaSpanvalueWriter(out *bytes.Buffer, rs *sppb.ResultSet) error {
csvWriter := svwriter.NewCSVWriter(out, svwriter.WithMetadata(rs.GetMetadata()))
csvWriter, err := svwriter.NewCSVWriter(out, svwriter.WithMetadata(rs.GetMetadata()))
if err != nil {
return err
}
for _, row := range rs.GetRows() {
if err := csvWriter.WriteStructValues(row.GetValues()); err != nil {
return err
Expand All @@ -150,7 +157,10 @@ func experimentalCsvViaSpanvalueWriter(out *bytes.Buffer, rs *sppb.ResultSet) er

// writeCsvFromPreparedRows exercises the WriteRow path after PrepareRowType, matching production.
func writeCsvFromPreparedRows(w io.Writer, metadata *sppb.ResultSetMetadata, rows []*spanner.Row) error {
csvWriter := svwriter.NewCSVWriter(w)
csvWriter, err := svwriter.NewCSVWriter(w)
if err != nil {
return err
}
if err := prepareCsvRowType(csvWriter, metadata); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/apstndb/memebridge v0.6.0
github.com/apstndb/spanemuboost v0.0.0-20241212215948-d4eb945c8f10
github.com/apstndb/spannerotel v0.0.0-20220113012943-45b1c9cc5afb
github.com/apstndb/spanvalue v0.4.1
github.com/apstndb/spanvalue v0.5.0
github.com/cloudspannerecosystem/memefish v0.6.2
github.com/google/go-cmp v0.7.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,8 @@ github.com/apstndb/spannerotel v0.0.0-20220113012943-45b1c9cc5afb h1:wop6M8ZQWhV
github.com/apstndb/spannerotel v0.0.0-20220113012943-45b1c9cc5afb/go.mod h1:H9relGptAtWqSNrJy+V1jiYPeBIk8KYh6lACV3VZrqU=
github.com/apstndb/spantype v0.3.11 h1:wKue4WLYGT82MH3B3TRSFn8tWIbk1Geczs+5BAEtnK4=
github.com/apstndb/spantype v0.3.11/go.mod h1:9eHowE7LcJ155ukCYUyuNzVAw9Ne0GXPXpHmu+iaMyk=
github.com/apstndb/spanvalue v0.4.1 h1:5G4TzCb5KPovcx8dsmRu81dKOyKydMaJlWgJdomTutI=
github.com/apstndb/spanvalue v0.4.1/go.mod h1:xKnvCW0eC+EtZfICvyesMpr/PJTY8tXjcWR+i0x0dZw=
github.com/apstndb/spanvalue v0.5.0 h1:91RfaKX6WRDNDQrNmo9lO6O0sUS0x+4YxRBylDfS0xM=
github.com/apstndb/spanvalue v0.5.0/go.mod h1:xKnvCW0eC+EtZfICvyesMpr/PJTY8tXjcWR+i0x0dZw=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
Expand Down
12 changes: 9 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,15 @@ func runAndWriteCsv(ctx context.Context, client *spanner.Client, stmt spanner.St
}

// writeCsvFromRowIter streams query rows to CSV without materializing a ResultSet.
// It follows spanvalue v0.4.1 RowIterator guidance: PrepareRowType after the first Next
// It follows spanvalue RowIterator guidance: PrepareRowType after the first Next
// (including iterator.Done), WriteRow in the loop, return Flush (not defer Flush).
func writeCsvFromRowIter(writer io.Writer, rowIter *spanner.RowIterator, redactRows bool) error {
defer rowIter.Stop()

csvWriter := svwriter.NewCSVWriter(writer)
csvWriter, err := svwriter.NewCSVWriter(writer)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking note: for the CSV case this error branch is effectively unreachable. NewCSVWriter only surfaces a configuration error for an invalid delimiter (Comma is hard-coded and always valid) or a failing option, and none of the call sites pass a fallible option. Handling it is still the right thing to do given the new signature, just flagging that it won't fire in practice.

if err != nil {
return err
}

if redactRows {
if err := skipRowIter(rowIter); err != nil {
Expand Down Expand Up @@ -432,7 +435,10 @@ func writeCsvFromResultSet(writer io.Writer, rs *sppb.ResultSet) error {
return errors.New("result set metadata is missing or invalid")
}

csvWriter := svwriter.NewCSVWriter(writer, svwriter.WithMetadata(rs.GetMetadata()))
csvWriter, err := svwriter.NewCSVWriter(writer, svwriter.WithMetadata(rs.GetMetadata()))
if err != nil {
return err
}
for _, row := range rs.GetRows() {
if row == nil {
return fmt.Errorf("nil row in result set")
Expand Down
2 changes: 1 addition & 1 deletion testdata/experimental_csv/numeric.golden
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
v
99.500000000
99.5

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed intentional: spanvalue v0.5.0 SimpleFormatConfig emits the NUMERIC wire decimal string as-is (no nine-digit scale padding), and the release notes explicitly call out regoldening CSV/JSONL exports when upgrading from v0.4.1 or older. This is a user-visible output change for the experimental_csv format's NUMERIC columns; acceptable given the format is still experimental.

Loading