From c4f480a8398a51452dee5238eab7ecf6add5e2c2 Mon Sep 17 00:00:00 2001 From: Yao Zongyou Date: Sat, 6 Jul 2019 03:08:56 +0800 Subject: [PATCH] fix csv read bug (#7885) --- pkg/s3select/csv/reader.go | 2 +- pkg/s3select/csv/reader_test.go | 72 +++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 pkg/s3select/csv/reader_test.go diff --git a/pkg/s3select/csv/reader.go b/pkg/s3select/csv/reader.go index b917a4139..3438d09d4 100644 --- a/pkg/s3select/csv/reader.go +++ b/pkg/s3select/csv/reader.go @@ -59,10 +59,10 @@ func (rr *recordReader) Read(p []byte) (n int, err error) { p[i] = '\n' if len(rr.recordDelimiter) > 1 { p = append(p[:i+1], p[i+len(rr.recordDelimiter):]...) + n-- } } - n = len(p) if len(rr.recordDelimiter) == 1 || p[n-1] != rr.recordDelimiter[0] { return n, nil } diff --git a/pkg/s3select/csv/reader_test.go b/pkg/s3select/csv/reader_test.go new file mode 100644 index 000000000..68b222ef7 --- /dev/null +++ b/pkg/s3select/csv/reader_test.go @@ -0,0 +1,72 @@ +/* + * MinIO Cloud Storage, (C) 2019 MinIO, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package csv + +import ( + "io" + "io/ioutil" + "strings" + "testing" + + "github.com/minio/minio/pkg/s3select/sql" +) + +func TestRead(t *testing.T) { + cases := []struct { + content string + recordDelimiter string + fieldDelimiter string + }{ + {"1,2,3\na,b,c\n", "\n", ","}, + {"1,2,3\ta,b,c\t", "\t", ","}, + {"1,2,3\r\na,b,c\r\n", "\r\n", ","}, + } + + for i, c := range cases { + var err error + var record sql.Record + + r, _ := NewReader(ioutil.NopCloser(strings.NewReader(c.content)), &ReaderArgs{ + FileHeaderInfo: none, + RecordDelimiter: c.recordDelimiter, + FieldDelimiter: c.fieldDelimiter, + QuoteCharacter: defaultQuoteCharacter, + QuoteEscapeCharacter: defaultQuoteEscapeCharacter, + CommentCharacter: defaultCommentCharacter, + AllowQuotedRecordDelimiter: true, + unmarshaled: true, + }) + + result := "" + for { + record, err = r.Read() + if err != nil { + break + } + s, _ := record.MarshalCSV([]rune(c.fieldDelimiter)[0]) + result += string(s) + c.recordDelimiter + } + r.Close() + if err != io.EOF { + t.Fatalf("Case %d failed with %s", i, err) + } + + if result != c.content { + t.Errorf("Case %d failed: expected %v result %v", i, c.content, result) + } + } +}