mirror of
https://github.com/minio/minio.git
synced 2025-04-20 10:37:31 -04:00
Treat columns with spaces inbetween [s3Select] (#6597)
replace the double/single quotes with backticks for the xwb1989/sqlparser to recognise such queries. Fixes #6589
This commit is contained in:
parent
c998d1ac8c
commit
cef044178c
@ -70,6 +70,12 @@ func setHeadGetRespHeaders(w http.ResponseWriter, reqParams url.Values) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function replaces "",'' with `` for the select parser
|
||||||
|
func cleanExpr(expr string) string {
|
||||||
|
r := strings.NewReplacer("\"", "`", "'", "`")
|
||||||
|
return r.Replace(expr)
|
||||||
|
}
|
||||||
|
|
||||||
// SelectObjectContentHandler - GET Object?select
|
// SelectObjectContentHandler - GET Object?select
|
||||||
// ----------
|
// ----------
|
||||||
// This implementation of the GET operation retrieves object content based
|
// This implementation of the GET operation retrieves object content based
|
||||||
@ -255,7 +261,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r
|
|||||||
Name: "S3Object", // Default table name for all objects
|
Name: "S3Object", // Default table name for all objects
|
||||||
ReadFrom: gr,
|
ReadFrom: gr,
|
||||||
Compressed: string(selectReq.InputSerialization.CompressionType),
|
Compressed: string(selectReq.InputSerialization.CompressionType),
|
||||||
Expression: selectReq.Expression,
|
Expression: cleanExpr(selectReq.Expression),
|
||||||
OutputFieldDelimiter: selectReq.OutputSerialization.CSV.FieldDelimiter,
|
OutputFieldDelimiter: selectReq.OutputSerialization.CSV.FieldDelimiter,
|
||||||
StreamSize: objInfo.Size,
|
StreamSize: objInfo.Size,
|
||||||
HeaderOpt: selectReq.InputSerialization.CSV.FileHeaderInfo == CSVFileHeaderInfoUse,
|
HeaderOpt: selectReq.InputSerialization.CSV.FileHeaderInfo == CSVFileHeaderInfoUse,
|
||||||
@ -266,7 +272,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r
|
|||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, _, _, _, _, _, err = s3s.ParseSelect(selectReq.Expression)
|
_, _, _, _, _, _, err = s3s.ParseSelect(options.Expression)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
|
@ -207,12 +207,6 @@ func (reader *Input) ReadRecord() []string {
|
|||||||
return row
|
return row
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertMySQL Replaces double quote escape for column names with backtick for
|
|
||||||
// the MySQL parser
|
|
||||||
func convertMySQL(random string) string {
|
|
||||||
return strings.Replace(random, "\"", "`", len(random))
|
|
||||||
}
|
|
||||||
|
|
||||||
// readHeader reads the header into the header variable if the header is present
|
// readHeader reads the header into the header variable if the header is present
|
||||||
// as the first row of the csv
|
// as the first row of the csv
|
||||||
func (reader *Input) readHeader() error {
|
func (reader *Input) readHeader() error {
|
||||||
@ -222,7 +216,7 @@ func (reader *Input) readHeader() error {
|
|||||||
if readErr != nil {
|
if readErr != nil {
|
||||||
return ErrCSVParsingError
|
return ErrCSVParsingError
|
||||||
}
|
}
|
||||||
reader.header = reader.firstRow
|
reader.header = cleanHeader(reader.firstRow)
|
||||||
reader.firstRow = nil
|
reader.firstRow = nil
|
||||||
reader.minOutputLength = len(reader.header)
|
reader.minOutputLength = len(reader.header)
|
||||||
} else {
|
} else {
|
||||||
@ -236,6 +230,14 @@ func (reader *Input) readHeader() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace the spaces in columnnames with underscores
|
||||||
|
func cleanHeader(columns []string) []string {
|
||||||
|
for i := 0; i < len(columns); i++ {
|
||||||
|
columns[i] = strings.Replace(columns[i], " ", "_", -1)
|
||||||
|
}
|
||||||
|
return columns
|
||||||
|
}
|
||||||
|
|
||||||
// createStatXML is the function which does the marshaling from the stat
|
// createStatXML is the function which does the marshaling from the stat
|
||||||
// structs into XML so that the progress and stat message can be sent
|
// structs into XML so that the progress and stat message can be sent
|
||||||
func (reader *Input) createStatXML() (string, error) {
|
func (reader *Input) createStatXML() (string, error) {
|
||||||
@ -296,7 +298,7 @@ func (reader *Input) Execute(writer io.Writer) error {
|
|||||||
continuationTimer := time.NewTimer(continuationTime)
|
continuationTimer := time.NewTimer(continuationTime)
|
||||||
defer progressTicker.Stop()
|
defer progressTicker.Stop()
|
||||||
defer continuationTimer.Stop()
|
defer continuationTimer.Stop()
|
||||||
go reader.runSelectParser(convertMySQL(reader.options.Expression), myRow)
|
go reader.runSelectParser(reader.options.Expression, myRow)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case row, ok := <-myRow:
|
case row, ok := <-myRow:
|
||||||
|
@ -50,7 +50,6 @@ func (reader *Input) runSelectParser(selectExpression string, myRow chan *Row) {
|
|||||||
// records, and the where clause.
|
// records, and the where clause.
|
||||||
func (reader *Input) ParseSelect(sqlInput string) ([]string, string, int64, interface{}, []string, *SelectFuncs, error) {
|
func (reader *Input) ParseSelect(sqlInput string) ([]string, string, int64, interface{}, []string, *SelectFuncs, error) {
|
||||||
// return columnNames, alias, limitOfRecords, whereclause,coalStore, nil
|
// return columnNames, alias, limitOfRecords, whereclause,coalStore, nil
|
||||||
|
|
||||||
stmt, err := sqlparser.Parse(sqlInput)
|
stmt, err := sqlparser.Parse(sqlInput)
|
||||||
var whereClause interface{}
|
var whereClause interface{}
|
||||||
var alias string
|
var alias string
|
||||||
|
@ -253,6 +253,7 @@ func TestMyParser(t *testing.T) {
|
|||||||
{"SELECT count(*) FROM S3OBJECT AS A WHERE col_name = 'Name' LIMIT 5", nil, []string{"*"}, "A", 5, []string{"count"}, []string{"col_name", "col_other", "name3", "name4"}},
|
{"SELECT count(*) FROM S3OBJECT AS A WHERE col_name = 'Name' LIMIT 5", nil, []string{"*"}, "A", 5, []string{"count"}, []string{"col_name", "col_other", "name3", "name4"}},
|
||||||
{"SELECT sum(col_name),sum(col_other) FROM S3OBJECT AS A WHERE col_name = 'Name' LIMIT 5", nil, []string{"col_name", "col_other"}, "A", 5, []string{"sum", "sum"}, []string{"col_name", "col_other"}},
|
{"SELECT sum(col_name),sum(col_other) FROM S3OBJECT AS A WHERE col_name = 'Name' LIMIT 5", nil, []string{"col_name", "col_other"}, "A", 5, []string{"sum", "sum"}, []string{"col_name", "col_other"}},
|
||||||
{"SELECT A.col_name FROM S3OBJECT AS A", nil, []string{"col_name"}, "A", 0, make([]string, 1), []string{"col_name", "col_other", "name3", "name4"}},
|
{"SELECT A.col_name FROM S3OBJECT AS A", nil, []string{"col_name"}, "A", 0, make([]string, 1), []string{"col_name", "col_other", "name3", "name4"}},
|
||||||
|
{"SELECT A.`col name` FROM S3OBJECT AS A", nil, []string{"col_name"}, "A", 0, make([]string, 1), []string{"col_name", "col_other", "name3", "name4"}},
|
||||||
{"SELECT A._col_name FROM S3OBJECT AS A", nil, []string{"col_name"}, "A", 0, make([]string, 1), []string{"col_name", "col_other", "name3", "name4"}},
|
{"SELECT A._col_name FROM S3OBJECT AS A", nil, []string{"col_name"}, "A", 0, make([]string, 1), []string{"col_name", "col_other", "name3", "name4"}},
|
||||||
{"SELECT A._col_name FROM S3OBJECT AS A WHERE randomname > 5", ErrMissingHeaders, nil, "", 0, nil, []string{"col_name", "col_other", "name3", "name4"}},
|
{"SELECT A._col_name FROM S3OBJECT AS A WHERE randomname > 5", ErrMissingHeaders, nil, "", 0, nil, []string{"col_name", "col_other", "name3", "name4"}},
|
||||||
{"SELECT A._col_name FROM S3OBJECT AS A WHERE A._11 > 5", ErrInvalidColumnIndex, nil, "", 0, nil, []string{"col_name", "col_other", "name3", "name4"}},
|
{"SELECT A._col_name FROM S3OBJECT AS A WHERE A._11 > 5", ErrInvalidColumnIndex, nil, "", 0, nil, []string{"col_name", "col_other", "name3", "name4"}},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user