// send sends the call to the server. func (c *conn) send(args Request) (*rows, error) { resp, err := c.sender.Send(args) if err != nil { return nil, err } // Set the session state even if the server returns an application error. // The server is responsible for constructing the correct session state // and sending it back. if c.session != nil { panic("connection has lingering session state") } c.session = resp.Session // Translate into rows r := &rows{} // Only use the last result to populate the response index := len(resp.Results) - 1 if index < 0 { return r, nil } // Check for any application errors. // TODO(vivek): We might want to bunch all errors found here into // a single error. for _, result := range resp.Results { if result.Error != nil { return nil, result.Error } } result := resp.Results[index] r.columns = make([]string, len(result.Columns)) for i, column := range result.Columns { r.columns[i] = column } r.rows = make([]row, len(result.Rows)) for i, p := range result.Rows { t := make(row, len(p.Values)) for j, datum := range p.Values { if datum.BoolVal != nil { t[j] = *datum.BoolVal } else if datum.IntVal != nil { t[j] = *datum.IntVal } else if datum.FloatVal != nil { t[j] = *datum.FloatVal } else if datum.BytesVal != nil { t[j] = datum.BytesVal } else if datum.StringVal != nil { t[j] = []byte(*datum.StringVal) } else if datum.TimeVal != nil { t[j] = time.Unix((*datum.TimeVal).Sec, int64((*datum.TimeVal).Nsec)).UTC() } if !driver.IsScanValue(t[j]) { panic(fmt.Sprintf("unsupported type %T returned by database", t[j])) } } r.rows[i] = t } return r, nil }
// Send sends the call to the server. func (c *conn) send(args sqlwire.Request) (*rows, error) { resp, err := c.sender.Send(args) if err != nil { return nil, err } if resp.Error != nil { return nil, resp.Error } c.session = resp.Session // Translate into rows r := &rows{} // Only use the last result to populate the response index := len(resp.Results) - 1 if index < 0 { return r, nil } result := resp.Results[index] r.columns = make([]string, len(result.Columns)) for i, column := range result.Columns { r.columns[i] = column } r.rows = make([]row, len(result.Rows)) for i, p := range result.Rows { t := make(row, len(p.Values)) for j, datum := range p.Values { if datum.BoolVal != nil { t[j] = *datum.BoolVal } else if datum.IntVal != nil { t[j] = *datum.IntVal } else if datum.UintVal != nil { // uint64 not supported by the driver.Value interface. if *datum.UintVal >= math.MaxInt64 { return &rows{}, fmt.Errorf("cannot convert very large uint64 %d returned by database", *datum.UintVal) } t[j] = int64(*datum.UintVal) } else if datum.FloatVal != nil { t[j] = *datum.FloatVal } else if datum.BytesVal != nil { t[j] = datum.BytesVal } else if datum.StringVal != nil { t[j] = []byte(*datum.StringVal) } if !driver.IsScanValue(t[j]) { panic(fmt.Sprintf("unsupported type %T returned by database", t[j])) } } r.rows[i] = t } return r, nil }