@@ -48,6 +48,8 @@ type joinIter struct {
48
48
rowSize int
49
49
scopeLen int
50
50
parentLen int
51
+
52
+ rowBuffer * sql.RowBuffer
51
53
}
52
54
53
55
func newJoinIter (ctx * sql.Context , b sql.NodeExecBuilder , j * plan.JoinNode , row sql.Row ) (sql.RowIter , error ) {
@@ -75,9 +77,10 @@ func newJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row
75
77
return nil , err
76
78
}
77
79
78
- parentLen := len ( row )
80
+ rowBuffer := sql . RowBufPool . Get ().( * sql. RowBuffer )
79
81
80
- primaryRow := make (sql.Row , parentLen + len (j .Left ().Schema ()))
82
+ parentLen := len (row )
83
+ primaryRow := rowBuffer .Get (parentLen + len (j .Left ().Schema ()))
81
84
copy (primaryRow , row )
82
85
83
86
return sql .NewSpanIter (span , & joinIter {
@@ -94,6 +97,8 @@ func newJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row
94
97
rowSize : parentLen + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
95
98
scopeLen : j .ScopeLen ,
96
99
parentLen : parentLen ,
100
+
101
+ rowBuffer : rowBuffer ,
97
102
}), nil
98
103
}
99
104
@@ -200,13 +205,16 @@ func (i *joinIter) removeParentRow(r sql.Row) sql.Row {
200
205
201
206
// buildRow builds the result set row using the rows from the primary and secondary tables
202
207
func (i * joinIter ) buildRow (primary , secondary sql.Row ) sql.Row {
203
- row := make (sql. Row , i .rowSize )
208
+ row := i . rowBuffer . Get ( i .rowSize )
204
209
copy (row , primary )
205
210
copy (row [len (primary ):], secondary )
206
211
return row
207
212
}
208
213
209
214
func (i * joinIter ) Close (ctx * sql.Context ) (err error ) {
215
+ i .rowBuffer .Reset ()
216
+ sql .RowBufPool .Put (i .rowBuffer )
217
+
210
218
if i .primary != nil {
211
219
if err = i .primary .Close (ctx ); err != nil {
212
220
if i .secondary != nil {
@@ -232,11 +240,13 @@ func newExistsIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, ro
232
240
233
241
parentLen := len (row )
234
242
243
+ rowBuffer := sql .RowBufPool .Get ().(* sql.RowBuffer )
244
+
235
245
rowSize := parentLen + len (j .Left ().Schema ()) + len (j .Right ().Schema ())
236
- fullRow := make (sql. Row , rowSize )
246
+ fullRow := rowBuffer . Get ( rowSize )
237
247
copy (fullRow , row )
238
248
239
- primaryRow := make (sql. Row , parentLen + len (j .Left ().Schema ()))
249
+ primaryRow := rowBuffer . Get ( parentLen + len (j .Left ().Schema ()))
240
250
copy (primaryRow , row )
241
251
242
252
return & existsIter {
@@ -251,6 +261,7 @@ func newExistsIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, ro
251
261
scopeLen : j .ScopeLen ,
252
262
rowSize : rowSize ,
253
263
nullRej : ! (j .Filter != nil && plan .IsNullRejecting (j .Filter )),
264
+ rowBuffer : rowBuffer ,
254
265
}, nil
255
266
}
256
267
@@ -271,6 +282,8 @@ type existsIter struct {
271
282
272
283
nullRej bool
273
284
rightIterNonEmpty bool
285
+
286
+ rowBuffer * sql.RowBuffer
274
287
}
275
288
276
289
type existsState uint8
@@ -396,13 +409,16 @@ func (i *existsIter) removeParentRow(r sql.Row) sql.Row {
396
409
397
410
// buildRow builds the result set row using the rows from the primary and secondary tables
398
411
func (i * existsIter ) buildRow (primary , secondary sql.Row ) sql.Row {
399
- row := make (sql. Row , i .rowSize )
412
+ row := i . rowBuffer . Get ( i .rowSize )
400
413
copy (row , primary )
401
414
copy (row [len (primary ):], secondary )
402
415
return row
403
416
}
404
417
405
418
func (i * existsIter ) Close (ctx * sql.Context ) (err error ) {
419
+ i .rowBuffer .Reset ()
420
+ sql .RowBufPool .Put (i .rowBuffer )
421
+
406
422
if i .primary != nil {
407
423
if err = i .primary .Close (ctx ); err != nil {
408
424
return err
@@ -411,26 +427,6 @@ func (i *existsIter) Close(ctx *sql.Context) (err error) {
411
427
return err
412
428
}
413
429
414
- func newFullJoinIter (ctx * sql.Context , b sql.NodeExecBuilder , j * plan.JoinNode , row sql.Row ) (sql.RowIter , error ) {
415
- leftIter , err := b .Build (ctx , j .Left (), row )
416
- if err != nil {
417
- return nil , err
418
- }
419
- return & fullJoinIter {
420
- parentRow : row ,
421
- l : leftIter ,
422
- rp : j .Right (),
423
- cond : j .Filter ,
424
- scopeLen : j .ScopeLen ,
425
- rowSize : len (row ) + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
426
- seenLeft : make (map [uint64 ]struct {}),
427
- seenRight : make (map [uint64 ]struct {}),
428
- leftLen : len (j .Left ().Schema ()),
429
- rightLen : len (j .Right ().Schema ()),
430
- b : b ,
431
- }, nil
432
- }
433
-
434
430
// fullJoinIter implements full join as a union of left and right join:
435
431
// FJ(A,B) => U(LJ(A,B), RJ(A,B)). The current algorithm will have a
436
432
// runtime and memory complexity O(m+n).
@@ -451,6 +447,30 @@ type fullJoinIter struct {
451
447
leftDone bool
452
448
seenLeft map [uint64 ]struct {}
453
449
seenRight map [uint64 ]struct {}
450
+
451
+ rowBuffer * sql.RowBuffer
452
+ }
453
+
454
+ func newFullJoinIter (ctx * sql.Context , b sql.NodeExecBuilder , j * plan.JoinNode , row sql.Row ) (sql.RowIter , error ) {
455
+ leftIter , err := b .Build (ctx , j .Left (), row )
456
+ if err != nil {
457
+ return nil , err
458
+ }
459
+ return & fullJoinIter {
460
+ parentRow : row ,
461
+ l : leftIter ,
462
+ rp : j .Right (),
463
+ cond : j .Filter ,
464
+ scopeLen : j .ScopeLen ,
465
+ rowSize : len (row ) + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
466
+ seenLeft : make (map [uint64 ]struct {}),
467
+ seenRight : make (map [uint64 ]struct {}),
468
+ leftLen : len (j .Left ().Schema ()),
469
+ rightLen : len (j .Right ().Schema ()),
470
+ b : b ,
471
+
472
+ rowBuffer : sql .RowBufPool .Get ().(* sql.RowBuffer ),
473
+ }, nil
454
474
}
455
475
456
476
func (i * fullJoinIter ) Next (ctx * sql.Context ) (sql.Row , error ) {
@@ -546,7 +566,7 @@ func (i *fullJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
546
566
continue
547
567
}
548
568
// (null, right) only if we haven't matched right
549
- ret := make (sql. Row , i .rowSize )
569
+ ret := i . rowBuffer . Get ( i .rowSize )
550
570
copy (ret [i .leftLen :], rightRow )
551
571
return i .removeParentRow (ret ), nil
552
572
}
@@ -560,13 +580,16 @@ func (i *fullJoinIter) removeParentRow(r sql.Row) sql.Row {
560
580
561
581
// buildRow builds the result set row using the rows from the primary and secondary tables
562
582
func (i * fullJoinIter ) buildRow (primary , secondary sql.Row ) sql.Row {
563
- row := make (sql. Row , i .rowSize )
583
+ row := i . rowBuffer . Get ( i .rowSize )
564
584
copy (row , primary )
565
585
copy (row [len (primary ):], secondary )
566
586
return row
567
587
}
568
588
569
589
func (i * fullJoinIter ) Close (ctx * sql.Context ) (err error ) {
590
+ i .rowBuffer .Reset ()
591
+ sql .RowBufPool .Put (i .rowBuffer )
592
+
570
593
if i .l != nil {
571
594
err = i .l .Close (ctx )
572
595
}
@@ -593,6 +616,8 @@ type crossJoinIterator struct {
593
616
rowSize int
594
617
scopeLen int
595
618
parentLen int
619
+
620
+ rowBuffer * sql.RowBuffer
596
621
}
597
622
598
623
func newCrossJoinIter (ctx * sql.Context , b sql.NodeExecBuilder , j * plan.JoinNode , row sql.Row ) (sql.RowIter , error ) {
@@ -620,9 +645,10 @@ func newCrossJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
620
645
return nil , err
621
646
}
622
647
623
- parentLen := len ( row )
648
+ rowBuffer := sql . RowBufPool . Get ().( * sql. RowBuffer )
624
649
625
- primaryRow := make (sql.Row , parentLen + len (j .Left ().Schema ()))
650
+ parentLen := len (row )
651
+ primaryRow := rowBuffer .Get (parentLen + len (j .Left ().Schema ()))
626
652
copy (primaryRow , row )
627
653
628
654
return sql .NewSpanIter (span , & crossJoinIterator {
@@ -635,6 +661,8 @@ func newCrossJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
635
661
rowSize : len (row ) + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
636
662
scopeLen : j .ScopeLen ,
637
663
parentLen : parentLen ,
664
+
665
+ rowBuffer : rowBuffer ,
638
666
}), nil
639
667
}
640
668
@@ -664,7 +692,7 @@ func (i *crossJoinIterator) Next(ctx *sql.Context) (sql.Row, error) {
664
692
return nil , err
665
693
}
666
694
667
- row := make (sql. Row , i .rowSize )
695
+ row := i . rowBuffer . Get ( i .rowSize )
668
696
copy (row , i .primaryRow )
669
697
copy (row [len (i .primaryRow ):], rightRow )
670
698
return i .removeParentRow (row ), nil
@@ -678,6 +706,9 @@ func (i *crossJoinIterator) removeParentRow(r sql.Row) sql.Row {
678
706
}
679
707
680
708
func (i * crossJoinIterator ) Close (ctx * sql.Context ) (err error ) {
709
+ i .rowBuffer .Reset () // TODO: just set i.rowBuffer = nil?
710
+ sql .RowBufPool .Put (i .rowBuffer )
711
+
681
712
if i .l != nil {
682
713
err = i .l .Close (ctx )
683
714
}
@@ -734,6 +765,8 @@ type lateralJoinIterator struct {
734
765
foundMatch bool
735
766
736
767
b sql.NodeExecBuilder
768
+
769
+ rowBuffer * sql.RowBuffer
737
770
}
738
771
739
772
func newLateralJoinIter (ctx * sql.Context , b sql.NodeExecBuilder , j * plan.JoinNode , row sql.Row ) (sql.RowIter , error ) {
@@ -769,6 +802,8 @@ func newLateralJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNod
769
802
rowSize : len (row ) + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
770
803
scopeLen : j .ScopeLen ,
771
804
b : b ,
805
+
806
+ rowBuffer : sql .RowBufPool .Get ().(* sql.RowBuffer ),
772
807
}), nil
773
808
}
774
809
@@ -811,7 +846,7 @@ func (i *lateralJoinIterator) loadRight(ctx *sql.Context) error {
811
846
}
812
847
813
848
func (i * lateralJoinIterator ) buildRow (lRow , rRow sql.Row ) sql.Row {
814
- row := make (sql. Row , i .rowSize )
849
+ row := i . rowBuffer . Get ( i .rowSize )
815
850
copy (row , lRow )
816
851
copy (row [len (lRow ):], rRow )
817
852
return row
@@ -874,6 +909,9 @@ func (i *lateralJoinIterator) Next(ctx *sql.Context) (sql.Row, error) {
874
909
}
875
910
876
911
func (i * lateralJoinIterator ) Close (ctx * sql.Context ) error {
912
+ i .rowBuffer .Reset ()
913
+ sql .RowBufPool .Put (i .rowBuffer )
914
+
877
915
var lerr , rerr error
878
916
if i .lIter != nil {
879
917
lerr = i .lIter .Close (ctx )
0 commit comments