// Next implements Executor Next interface. // The data in the returned row is not used by caller. func (e *JoinInnerExec) Next() (*Row, error) { if e.done { return nil, nil } rowKeysSlice := make([][]*RowKeyEntry, len(e.InnerPlans)) for { exec := e.innerExecs[e.cursor] if exec == nil { innerPlan := e.InnerPlans[e.cursor] plan.Refine(innerPlan) exec = e.builder.build(innerPlan) if e.builder.err != nil { return nil, errors.Trace(e.builder.err) } e.innerExecs[e.cursor] = exec } row, err := exec.Next() if err != nil { return nil, errors.Trace(err) } if row == nil { exec.Close() e.innerExecs[e.cursor] = nil if e.cursor == 0 { e.done = true return nil, nil } e.cursor-- continue } rowKeysSlice[e.cursor] = row.RowKeys if e.cursor < len(e.innerExecs)-1 { e.cursor++ continue } var match = true if e.Condition != nil { match, err = evaluator.EvalBool(e.ctx, e.Condition) if err != nil { return nil, errors.Trace(err) } } if match { row.RowKeys = joinRowKeys(rowKeysSlice) return row, nil } } }
func (sq *subquery) EvalRows(ctx context.Context, rowCount int) ([]types.Datum, error) { b := newExecutorBuilder(ctx, sq.is) plan.Refine(sq.plan) e := b.build(sq.plan) if b.err != nil { return nil, errors.Trace(b.err) } defer e.Close() if len(e.Fields()) == 0 { // No result fields means no Recordset. for { row, err := e.Next() if err != nil { return nil, errors.Trace(err) } if row == nil { return nil, nil } } } var ( err error row *Row rows []types.Datum ) for rowCount != 0 { row, err = e.Next() if err != nil { return rows, errors.Trace(err) } if row == nil { break } if len(row.Data) == 1 { rows = append(rows, row.Data[0]) } else { var d types.Datum d.SetRow(row.Data) rows = append(rows, d) } if rowCount > 0 { rowCount-- } } return rows, nil }
// Next implements Executor Next interface. // The data in the returned row is not used by caller. // If inner executor didn't get any row for an outer executor row, // a row with 0 len Data indicates there is no inner row matched for // an outer row. func (e *JoinOuterExec) Next() (*Row, error) { var rowKeys []*RowKeyEntry for { if e.innerExec == nil { e.gotRow = false outerRow, err := e.OuterExec.Next() if err != nil { return nil, errors.Trace(err) } if outerRow == nil { return nil, nil } rowKeys = outerRow.RowKeys plan.Refine(e.InnerPlan) e.innerExec = e.builder.build(e.InnerPlan) if e.builder.err != nil { return nil, errors.Trace(e.builder.err) } } row, err := e.innerExec.Next() if err != nil { return nil, errors.Trace(err) } if row == nil { e.innerExec.Close() e.innerExec = nil if e.gotRow { continue } e.setInnerNull() return &Row{RowKeys: rowKeys}, nil } if len(row.Data) != 0 { e.gotRow = true row.RowKeys = append(rowKeys, row.RowKeys...) return row, nil } } }