func (c *ClientConn) loadResultWithFuncIntoMap(rs []*mysql.Result, groupByIndexs []int, funcExprs map[int]string) (map[string]*ResultRow, error) { resultMap := make(map[string]*ResultRow) rt := new(mysql.Result) rt.Resultset = new(mysql.Resultset) rt.Fields = rs[0].Fields //change Result into map for _, r := range rs { for i := 0; i < len(r.Values); i++ { keySlice := r.Values[i][groupByIndexs[0]:] mk, err := c.generateMapKey(keySlice) if err != nil { return nil, err } if v, ok := resultMap[mk]; ok { //init rt rt.Values = nil rt.RowDatas = nil //append v and r into rt, and calculate the function value rt.Values = append(rt.Values, r.Values[i], v.Value) rt.RowDatas = append(rt.RowDatas, r.RowDatas[i], v.RowData) resultTmp := []*mysql.Result{rt} for funcIndex, funcName := range funcExprs { funcValue, err := c.calFuncExprValue(funcName, resultTmp, funcIndex) if err != nil { return nil, err } //set the function value in group by resultMap[mk].Value[funcIndex] = funcValue } } else { //key is not exist resultMap[mk] = &ResultRow{ Value: r.Values[i], RowData: r.RowDatas[i], } } } } return resultMap, nil }
func (c *Conn) readResultRows(result *mysql.Result, isBinary bool) (err error) { var data []byte for { data, err = c.readPacket() if err != nil { return } // EOF Packet if c.isEOFPacket(data) { if c.capability&mysql.CLIENT_PROTOCOL_41 > 0 { //result.Warnings = binary.LittleEndian.Uint16(data[1:]) //todo add strict_mode, warning will be treat as error result.Status = binary.LittleEndian.Uint16(data[3:]) c.status = result.Status } break } result.RowDatas = append(result.RowDatas, data) } result.Values = make([][]interface{}, len(result.RowDatas)) for i := range result.Values { result.Values[i], err = result.RowDatas[i].Parse(result.Fields, isBinary) if err != nil { return err } } return nil }