// queryRows implements the queryRunner interface. func (p *planner) queryRows(sql string, args ...interface{}) ([]parser.DTuple, error) { plan, err := p.query(sql, args...) if err != nil { return nil, err } defer plan.Close() if err := plan.Start(); err != nil { return nil, err } if next, err := plan.Next(); err != nil || !next { return nil, err } var rows []parser.DTuple for { if values := plan.Values(); values != nil { valCopy := append(parser.DTuple(nil), values...) rows = append(rows, valCopy) } next, err := plan.Next() if err != nil { return nil, err } if !next { break } } return rows, nil }
package sql import ( "fmt" "unsafe" "github.com/cockroachdb/cockroach/pkg/sql/mon" "github.com/cockroachdb/cockroach/pkg/sql/parser" ) const ( // targetChunkSize is the target number of Datums in a RowContainer chunk. targetChunkSize = 64 sizeOfDatum = int64(unsafe.Sizeof(parser.Datum(nil))) sizeOfDTuple = int64(unsafe.Sizeof(parser.DTuple(nil))) ) // RowContainer is a container for rows of DTuples which tracks the // approximate amount of memory allocated for row data. // Rows must be added using AddRow(); once the work is done // the Close() method must be called to release the allocated memory. // // TODO(knz): this does not currently track the amount of memory used // for the outer array of DTuple references. type RowContainer struct { numCols int // rowsPerChunk is the number of rows in a chunk; we pack multiple rows in a // single []Datum to reduce the overhead of the slice if we have few columns. rowsPerChunk int