@@ -54,44 +54,54 @@ func newJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, row
5454 span .End ()
5555 return nil , err
5656 }
57+
58+ parentLen := len (row )
59+
60+ primaryRow := make (sql.Row , parentLen + len (j .Left ().Schema ()))
61+ copy (primaryRow , row )
62+
5763 return sql .NewSpanIter (span , & joinIter {
58- parentRow : row ,
64+ primaryRow : primaryRow ,
65+ loadPrimaryRow : true ,
5966 primary : l ,
6067 secondaryProvider : j .Right (),
6168 cond : j .Filter ,
6269 joinType : j .Op ,
63- rowSize : len ( row ) + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
70+ rowSize : parentLen + len (j .Left ().Schema ()) + len (j .Right ().Schema ()),
6471 scopeLen : j .ScopeLen ,
72+ parentLen : parentLen ,
6573 b : b ,
6674 }), nil
6775}
6876
6977// joinIter is an iterator that iterates over every row in the primary table and performs an index lookup in
7078// the secondary table for each value
7179type joinIter struct {
72- parentRow sql.Row
7380 primary sql.RowIter
7481 primaryRow sql.Row
7582 secondaryProvider sql.Node
7683 secondary sql.RowIter
7784 cond sql.Expression
7885 joinType plan.JoinType
7986
87+ loadPrimaryRow bool
88+
8089 foundMatch bool
8190 rowSize int
8291 scopeLen int
92+ parentLen int
8393 b sql.NodeExecBuilder
8494}
8595
8696func (i * joinIter ) loadPrimary (ctx * sql.Context ) error {
87- if i .primaryRow == nil {
97+ if i .loadPrimaryRow {
8898 r , err := i .primary .Next (ctx )
8999 if err != nil {
90100 return err
91101 }
92-
93- i .primaryRow = i .parentRow .Append (r )
102+ copy (i .primaryRow [i .parentLen :], r )
94103 i .foundMatch = false
104+ i .loadPrimaryRow = false
95105 }
96106
97107 return nil
@@ -118,7 +128,7 @@ func (i *joinIter) loadSecondary(ctx *sql.Context) (sql.Row, error) {
118128 if err != nil {
119129 return nil , err
120130 }
121- i .primaryRow = nil
131+ i .loadPrimaryRow = true
122132 return nil , io .EOF
123133 }
124134 return nil , err
@@ -138,14 +148,14 @@ func (i *joinIter) Next(ctx *sql.Context) (sql.Row, error) {
138148 if err != nil {
139149 if errors .Is (err , io .EOF ) {
140150 if ! i .foundMatch && i .joinType .IsLeftOuter () {
141- i .primaryRow = nil
151+ i .loadPrimaryRow = true
142152 row := i .buildRow (primary , nil )
143153 return i .removeParentRow (row ), nil
144154 }
145155 continue
146156 } else if errors .Is (err , plan .ErrEmptyCachedResult ) {
147157 if ! i .foundMatch && i .joinType .IsLeftOuter () {
148- i .primaryRow = nil
158+ i .loadPrimaryRow = true
149159 row := i .buildRow (primary , nil )
150160 return i .removeParentRow (row ), nil
151161 }
@@ -167,7 +177,7 @@ func (i *joinIter) Next(ctx *sql.Context) (sql.Row, error) {
167177 if err != nil {
168178 return nil , err
169179 }
170- i .primaryRow = nil
180+ i .loadPrimaryRow = true
171181 continue
172182 }
173183
@@ -181,8 +191,8 @@ func (i *joinIter) Next(ctx *sql.Context) (sql.Row, error) {
181191}
182192
183193func (i * joinIter ) removeParentRow (r sql.Row ) sql.Row {
184- copy (r [i .scopeLen :], r [len ( i . parentRow ) :])
185- r = r [:len (r )- len ( i . parentRow ) + i .scopeLen ]
194+ copy (r [i .scopeLen :], r [i . parentLen :])
195+ r = r [:len (r )- i . parentLen + i .scopeLen ]
186196 return r
187197}
188198
@@ -216,37 +226,50 @@ func (i *joinIter) Close(ctx *sql.Context) (err error) {
216226
217227func newExistsIter (ctx * sql.Context , b sql.NodeExecBuilder , j * plan.JoinNode , row sql.Row ) (sql.RowIter , error ) {
218228 leftIter , err := b .Build (ctx , j .Left (), row )
219-
220229 if err != nil {
221230 return nil , err
222231 }
232+
233+ parentLen := len (row )
234+
235+ rowSize := parentLen + len (j .Left ().Schema ()) + len (j .Right ().Schema ())
236+ fullRow := make (sql.Row , rowSize )
237+ copy (fullRow , row )
238+
239+ primaryRow := make (sql.Row , parentLen + len (j .Left ().Schema ()))
240+ copy (primaryRow , row )
241+
223242 return & existsIter {
224- parentRow : row ,
243+ b : b ,
225244 typ : j .Op ,
226245 primary : leftIter ,
246+ primaryRow : primaryRow ,
247+ fullRow : fullRow ,
248+ parentLen : parentLen ,
227249 secondaryProvider : j .Right (),
228250 cond : j .Filter ,
229251 scopeLen : j .ScopeLen ,
230- rowSize : len ( row ) + len ( j . Left (). Schema ()) + len ( j . Right (). Schema ()) ,
252+ rowSize : rowSize ,
231253 nullRej : ! (j .Filter != nil && plan .IsNullRejecting (j .Filter )),
232- b : b ,
233254 }, nil
234255}
235256
236257type existsIter struct {
258+ b sql.NodeExecBuilder
237259 typ plan.JoinType
238- primary sql.RowIter
239260 secondaryProvider sql.Node
240261 cond sql.Expression
241262
263+ primary sql.RowIter
242264 primaryRow sql.Row
265+ fullRow sql.Row
266+
267+ parentLen int
268+ scopeLen int
269+ rowSize int
243270
244- parentRow sql.Row
245- scopeLen int
246- rowSize int
247271 nullRej bool
248272 rightIterNonEmpty bool
249- b sql.NodeExecBuilder
250273}
251274
252275type existsState uint8
@@ -261,9 +284,7 @@ const (
261284)
262285
263286func (i * existsIter ) Next (ctx * sql.Context ) (sql.Row , error ) {
264- var row sql.Row
265287 var right sql.Row
266- var left sql.Row
267288 var rIter sql.RowIter
268289 var err error
269290
@@ -282,8 +303,9 @@ func (i *existsIter) Next(ctx *sql.Context) (sql.Row, error) {
282303 if err != nil {
283304 return nil , err
284305 }
285- left = i .parentRow .Append (r )
286- rIter , err = i .b .Build (ctx , i .secondaryProvider , left )
306+ copy (i .primaryRow [i .parentLen :], r )
307+ //i.primaryRow = i.parentRow.Append(r)
308+ rIter , err = i .b .Build (ctx , i .secondaryProvider , i .primaryRow )
287309 if err != nil {
288310 return nil , err
289311 }
@@ -319,8 +341,9 @@ func (i *existsIter) Next(ctx *sql.Context) (sql.Row, error) {
319341 nextState = esRet
320342 }
321343 case esCompare :
322- row = i .buildRow (left , right )
323- res , err := sql .EvaluateCondition (ctx , i .cond , row )
344+ copy (i .fullRow [i .parentLen :], i .primaryRow [i .parentLen :])
345+ copy (i .fullRow [len (i .primaryRow ):], right )
346+ res , err := sql .EvaluateCondition (ctx , i .cond , i .fullRow )
324347 if err != nil {
325348 return nil , err
326349 }
@@ -351,7 +374,7 @@ func (i *existsIter) Next(ctx *sql.Context) (sql.Row, error) {
351374 nextState = esIncRight
352375 }
353376 case esRet :
354- return i .removeParentRow (left ), nil
377+ return i .removeParentRow (i . primaryRow . Copy () ), nil
355378 default :
356379 return nil , fmt .Errorf ("invalid exists join state" )
357380 }
@@ -366,8 +389,8 @@ func isTrueLit(e sql.Expression) bool {
366389}
367390
368391func (i * existsIter ) removeParentRow (r sql.Row ) sql.Row {
369- copy (r [i .scopeLen :], r [len ( i . parentRow ) :])
370- r = r [:len (r )- len ( i . parentRow ) + i .scopeLen ]
392+ copy (r [i .scopeLen :], r [i . parentLen :])
393+ r = r [:len (r )- i . parentLen + i .scopeLen ]
371394 return r
372395}
373396
0 commit comments