Skip to content

add a sql.Row buffer #3151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,10 @@ func (h *Handler) resultForDefaultIter(ctx *sql.Context, c *mysql.Conn, schema s
defer wg.Done()
for {
if r == nil {
r = &sqltypes.Result{Fields: resultFields}
r = &sqltypes.Result{
Fields: resultFields,
Rows: make([][]sqltypes.Value, 0, rowsBatch),
}
}
if r.RowsAffected == rowsBatch {
if err := resetCallback(r, more); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion sql/expression/function/aggregation/window_partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (i *WindowPartitionIter) materializeInput(ctx *sql.Context) (sql.WindowBuff
}
return nil, nil, err
}
input = append(input, append(row, j))
input = append(input, append(append(sql.Row(nil), row...), j))
j++
}

Expand Down
107 changes: 75 additions & 32 deletions sql/rowexec/join_iters.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type joinIter struct {
rowSize int
scopeLen int
parentLen int

rowBuffer *sql.RowBuffer
}

func newJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row sql.Row) (sql.RowIter, error) {
Expand Down Expand Up @@ -75,9 +77,10 @@ func newJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row
return nil, err
}

parentLen := len(row)
rowBuffer := sql.RowBufPool.Get().(*sql.RowBuffer)

primaryRow := make(sql.Row, parentLen+len(j.Left().Schema()))
parentLen := len(row)
primaryRow := rowBuffer.Get(parentLen + len(j.Left().Schema()))
copy(primaryRow, row)

return sql.NewSpanIter(span, &joinIter{
Expand All @@ -94,6 +97,8 @@ func newJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row
rowSize: parentLen + len(j.Left().Schema()) + len(j.Right().Schema()),
scopeLen: j.ScopeLen,
parentLen: parentLen,

rowBuffer: rowBuffer,
}), nil
}

Expand Down Expand Up @@ -200,13 +205,17 @@ func (i *joinIter) removeParentRow(r sql.Row) sql.Row {

// buildRow builds the result set row using the rows from the primary and secondary tables
func (i *joinIter) buildRow(primary, secondary sql.Row) sql.Row {
row := make(sql.Row, i.rowSize)
row := i.rowBuffer.Get(i.rowSize)
copy(row, primary)
copy(row[len(primary):], secondary)
return row
}

func (i *joinIter) Close(ctx *sql.Context) (err error) {
//i.rowBuffer.Reset()
//sql.RowBufPool.Put(i.rowBuffer)
i.rowBuffer = nil

if i.primary != nil {
if err = i.primary.Close(ctx); err != nil {
if i.secondary != nil {
Expand All @@ -232,11 +241,13 @@ func newExistsIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, ro

parentLen := len(row)

rowBuffer := sql.RowBufPool.Get().(*sql.RowBuffer)

rowSize := parentLen + len(j.Left().Schema()) + len(j.Right().Schema())
fullRow := make(sql.Row, rowSize)
fullRow := rowBuffer.Get(rowSize)
copy(fullRow, row)

primaryRow := make(sql.Row, parentLen+len(j.Left().Schema()))
primaryRow := rowBuffer.Get(parentLen + len(j.Left().Schema()))
copy(primaryRow, row)

return &existsIter{
Expand All @@ -251,6 +262,7 @@ func newExistsIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, ro
scopeLen: j.ScopeLen,
rowSize: rowSize,
nullRej: !(j.Filter != nil && plan.IsNullRejecting(j.Filter)),
rowBuffer: rowBuffer,
}, nil
}

Expand All @@ -271,6 +283,8 @@ type existsIter struct {

nullRej bool
rightIterNonEmpty bool

rowBuffer *sql.RowBuffer
}

type existsState uint8
Expand Down Expand Up @@ -396,13 +410,17 @@ func (i *existsIter) removeParentRow(r sql.Row) sql.Row {

// buildRow builds the result set row using the rows from the primary and secondary tables
func (i *existsIter) buildRow(primary, secondary sql.Row) sql.Row {
row := make(sql.Row, i.rowSize)
row := i.rowBuffer.Get(i.rowSize)
copy(row, primary)
copy(row[len(primary):], secondary)
return row
}

func (i *existsIter) Close(ctx *sql.Context) (err error) {
i.rowBuffer = nil
//i.rowBuffer.Reset()
//sql.RowBufPool.Put(i.rowBuffer)

if i.primary != nil {
if err = i.primary.Close(ctx); err != nil {
return err
Expand All @@ -411,26 +429,6 @@ func (i *existsIter) Close(ctx *sql.Context) (err error) {
return err
}

func newFullJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row sql.Row) (sql.RowIter, error) {
leftIter, err := b.Build(ctx, j.Left(), row)
if err != nil {
return nil, err
}
return &fullJoinIter{
parentRow: row,
l: leftIter,
rp: j.Right(),
cond: j.Filter,
scopeLen: j.ScopeLen,
rowSize: len(row) + len(j.Left().Schema()) + len(j.Right().Schema()),
seenLeft: make(map[uint64]struct{}),
seenRight: make(map[uint64]struct{}),
leftLen: len(j.Left().Schema()),
rightLen: len(j.Right().Schema()),
b: b,
}, nil
}

// fullJoinIter implements full join as a union of left and right join:
// FJ(A,B) => U(LJ(A,B), RJ(A,B)). The current algorithm will have a
// runtime and memory complexity O(m+n).
Expand All @@ -451,6 +449,30 @@ type fullJoinIter struct {
leftDone bool
seenLeft map[uint64]struct{}
seenRight map[uint64]struct{}

rowBuffer *sql.RowBuffer
}

func newFullJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row sql.Row) (sql.RowIter, error) {
leftIter, err := b.Build(ctx, j.Left(), row)
if err != nil {
return nil, err
}
return &fullJoinIter{
parentRow: row,
l: leftIter,
rp: j.Right(),
cond: j.Filter,
scopeLen: j.ScopeLen,
rowSize: len(row) + len(j.Left().Schema()) + len(j.Right().Schema()),
seenLeft: make(map[uint64]struct{}),
seenRight: make(map[uint64]struct{}),
leftLen: len(j.Left().Schema()),
rightLen: len(j.Right().Schema()),
b: b,

rowBuffer: sql.RowBufPool.Get().(*sql.RowBuffer),
}, nil
}

func (i *fullJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
Expand Down Expand Up @@ -546,7 +568,7 @@ func (i *fullJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
continue
}
// (null, right) only if we haven't matched right
ret := make(sql.Row, i.rowSize)
ret := i.rowBuffer.Get(i.rowSize)
copy(ret[i.leftLen:], rightRow)
return i.removeParentRow(ret), nil
}
Expand All @@ -560,13 +582,17 @@ func (i *fullJoinIter) removeParentRow(r sql.Row) sql.Row {

// buildRow builds the result set row using the rows from the primary and secondary tables
func (i *fullJoinIter) buildRow(primary, secondary sql.Row) sql.Row {
row := make(sql.Row, i.rowSize)
row := i.rowBuffer.Get(i.rowSize)
copy(row, primary)
copy(row[len(primary):], secondary)
return row
}

func (i *fullJoinIter) Close(ctx *sql.Context) (err error) {
i.rowBuffer = nil
//i.rowBuffer.Reset()
//sql.RowBufPool.Put(i.rowBuffer)

if i.l != nil {
err = i.l.Close(ctx)
}
Expand All @@ -593,6 +619,8 @@ type crossJoinIterator struct {
rowSize int
scopeLen int
parentLen int

rowBuffer *sql.RowBuffer
}

func newCrossJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row sql.Row) (sql.RowIter, error) {
Expand Down Expand Up @@ -620,9 +648,10 @@ func newCrossJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
return nil, err
}

parentLen := len(row)
rowBuffer := sql.RowBufPool.Get().(*sql.RowBuffer)

primaryRow := make(sql.Row, parentLen+len(j.Left().Schema()))
parentLen := len(row)
primaryRow := rowBuffer.Get(parentLen + len(j.Left().Schema()))
copy(primaryRow, row)

return sql.NewSpanIter(span, &crossJoinIterator{
Expand All @@ -635,6 +664,8 @@ func newCrossJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
rowSize: len(row) + len(j.Left().Schema()) + len(j.Right().Schema()),
scopeLen: j.ScopeLen,
parentLen: parentLen,

rowBuffer: rowBuffer,
}), nil
}

Expand Down Expand Up @@ -664,7 +695,7 @@ func (i *crossJoinIterator) Next(ctx *sql.Context) (sql.Row, error) {
return nil, err
}

row := make(sql.Row, i.rowSize)
row := i.rowBuffer.Get(i.rowSize)
copy(row, i.primaryRow)
copy(row[len(i.primaryRow):], rightRow)
return i.removeParentRow(row), nil
Expand All @@ -678,6 +709,10 @@ func (i *crossJoinIterator) removeParentRow(r sql.Row) sql.Row {
}

func (i *crossJoinIterator) Close(ctx *sql.Context) (err error) {
i.rowBuffer = nil
//i.rowBuffer.Reset()
//sql.RowBufPool.Put(i.rowBuffer)

if i.l != nil {
err = i.l.Close(ctx)
}
Expand Down Expand Up @@ -734,6 +769,8 @@ type lateralJoinIterator struct {
foundMatch bool

b sql.NodeExecBuilder

rowBuffer *sql.RowBuffer
}

func newLateralJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row sql.Row) (sql.RowIter, error) {
Expand Down Expand Up @@ -769,6 +806,8 @@ func newLateralJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNod
rowSize: len(row) + len(j.Left().Schema()) + len(j.Right().Schema()),
scopeLen: j.ScopeLen,
b: b,

rowBuffer: sql.RowBufPool.Get().(*sql.RowBuffer),
}), nil
}

Expand Down Expand Up @@ -811,7 +850,7 @@ func (i *lateralJoinIterator) loadRight(ctx *sql.Context) error {
}

func (i *lateralJoinIterator) buildRow(lRow, rRow sql.Row) sql.Row {
row := make(sql.Row, i.rowSize)
row := i.rowBuffer.Get(i.rowSize)
copy(row, lRow)
copy(row[len(lRow):], rRow)
return row
Expand Down Expand Up @@ -874,6 +913,10 @@ func (i *lateralJoinIterator) Next(ctx *sql.Context) (sql.Row, error) {
}

func (i *lateralJoinIterator) Close(ctx *sql.Context) error {
i.rowBuffer = nil
//i.rowBuffer.Reset()
//sql.RowBufPool.Put(i.rowBuffer)

var lerr, rerr error
if i.lIter != nil {
lerr = i.lIter.Close(ctx)
Expand Down
12 changes: 9 additions & 3 deletions sql/rowexec/merge_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ func newMergeJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
return nil, err
}

fullRow := make(sql.Row, len(row)+len(j.Left().Schema())+len(j.Right().Schema()))
fullRow[0] = row
//fullRow := make(sql.Row, len(row)+len(j.Left().Schema())+len(j.Right().Schema()))

rowBuf := sql.RowBufPool.Get().(*sql.RowBuffer)
fullRow := rowBuf.Get(len(row) + len(j.Left().Schema()) + len(j.Right().Schema()))
//fullRow[0] = row
if len(row) > 0 {
copy(fullRow[0:], row[:])
}
Expand Down Expand Up @@ -83,6 +86,7 @@ func newMergeJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
leftRowLen: len(j.Left().Schema()),
rightRowLen: len(j.Right().Schema()),
isReversed: j.IsReversed,
rowBuffer: rowBuf,
}
return iter, nil
}
Expand Down Expand Up @@ -128,6 +132,8 @@ type mergeJoinIter struct {
leftRowLen int
rightRowLen int
parentLen int

rowBuffer *sql.RowBuffer
}

var _ sql.RowIter = (*mergeJoinIter)(nil)
Expand Down Expand Up @@ -314,7 +320,7 @@ func (i *mergeJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
}

func (i *mergeJoinIter) copyReturnRow() sql.Row {
ret := make(sql.Row, len(i.fullRow))
ret := i.rowBuffer.Get(len(i.fullRow))
copy(ret, i.fullRow)
return ret
}
Expand Down
13 changes: 11 additions & 2 deletions sql/rowexec/range_heap_iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type rangeHeapJoinIter struct {
childRowIter sql.RowIter
pendingRow sql.Row
activeRanges []sql.Row

rowBuffer *sql.RowBuffer
}

func newRangeHeapJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row sql.Row) (sql.RowIter, error) {
Expand Down Expand Up @@ -68,9 +70,11 @@ func newRangeHeapJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinN
return nil, errors.New("right side of join must be a range heap")
}

rowBuffer := sql.RowBufPool.Get().(*sql.RowBuffer)

parentLen := len(row)

primaryRow := make(sql.Row, parentLen+len(j.Left().Schema()))
primaryRow := rowBuffer.Get(parentLen + len(j.Left().Schema()))
copy(primaryRow, row)

return sql.NewSpanIter(span, &rangeHeapJoinIter{
Expand All @@ -88,6 +92,8 @@ func newRangeHeapJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinN
parentLen: parentLen,

rangeHeapPlan: rhp,

rowBuffer: rowBuffer,
}), nil
}

Expand Down Expand Up @@ -202,13 +208,16 @@ func (iter *rangeHeapJoinIter) removeParentRow(r sql.Row) sql.Row {

// buildRow builds the result set row using the rows from the primary and secondary tables
func (iter *rangeHeapJoinIter) buildRow(primary, secondary sql.Row) sql.Row {
row := make(sql.Row, iter.rowSize)
row := iter.rowBuffer.Get(iter.rowSize)
copy(row, primary)
copy(row[len(primary):], secondary)
return row
}

func (iter *rangeHeapJoinIter) Close(ctx *sql.Context) (err error) {
iter.rowBuffer.Reset()
sql.RowBufPool.Put(iter.rowBuffer)

if iter.primary != nil {
if err = iter.primary.Close(ctx); err != nil {
if iter.secondary != nil {
Expand Down
Loading
Loading