github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/rowexec/noop.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package rowexec
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/execinfrapb"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    20  )
    21  
    22  // noopProcessor is a processor that simply passes rows through from the
    23  // synchronizer to the post-processing stage. It can be useful for its
    24  // post-processing or in the last stage of a computation, where we may only
    25  // need the synchronizer to join streams.
    26  type noopProcessor struct {
    27  	execinfra.ProcessorBase
    28  	input execinfra.RowSource
    29  }
    30  
    31  var _ execinfra.Processor = &noopProcessor{}
    32  var _ execinfra.RowSource = &noopProcessor{}
    33  var _ execinfra.OpNode = &noopProcessor{}
    34  
    35  const noopProcName = "noop"
    36  
    37  func newNoopProcessor(
    38  	flowCtx *execinfra.FlowCtx,
    39  	processorID int32,
    40  	input execinfra.RowSource,
    41  	post *execinfrapb.PostProcessSpec,
    42  	output execinfra.RowReceiver,
    43  ) (*noopProcessor, error) {
    44  	n := &noopProcessor{input: input}
    45  	if err := n.Init(
    46  		n,
    47  		post,
    48  		input.OutputTypes(),
    49  		flowCtx,
    50  		processorID,
    51  		output,
    52  		nil, /* memMonitor */
    53  		execinfra.ProcStateOpts{InputsToDrain: []execinfra.RowSource{n.input}},
    54  	); err != nil {
    55  		return nil, err
    56  	}
    57  	return n, nil
    58  }
    59  
    60  // Start is part of the RowSource interface.
    61  func (n *noopProcessor) Start(ctx context.Context) context.Context {
    62  	n.input.Start(ctx)
    63  	return n.StartInternal(ctx, noopProcName)
    64  }
    65  
    66  // Next is part of the RowSource interface.
    67  func (n *noopProcessor) Next() (sqlbase.EncDatumRow, *execinfrapb.ProducerMetadata) {
    68  	for n.State == execinfra.StateRunning {
    69  		row, meta := n.input.Next()
    70  
    71  		if meta != nil {
    72  			if meta.Err != nil {
    73  				n.MoveToDraining(nil /* err */)
    74  			}
    75  			return nil, meta
    76  		}
    77  		if row == nil {
    78  			n.MoveToDraining(nil /* err */)
    79  			break
    80  		}
    81  
    82  		if outRow := n.ProcessRowHelper(row); outRow != nil {
    83  			return outRow, nil
    84  		}
    85  	}
    86  	return nil, n.DrainHelper()
    87  }
    88  
    89  // ConsumerClosed is part of the RowSource interface.
    90  func (n *noopProcessor) ConsumerClosed() {
    91  	// The consumer is done, Next() will not be called again.
    92  	n.InternalClose()
    93  }
    94  
    95  // ChildCount is part of the execinfra.OpNode interface.
    96  func (n *noopProcessor) ChildCount(bool) int {
    97  	if _, ok := n.input.(execinfra.OpNode); ok {
    98  		return 1
    99  	}
   100  	return 0
   101  }
   102  
   103  // Child is part of the execinfra.OpNode interface.
   104  func (n *noopProcessor) Child(nth int, _ bool) execinfra.OpNode {
   105  	if nth == 0 {
   106  		if n, ok := n.input.(execinfra.OpNode); ok {
   107  			return n
   108  		}
   109  		panic("input to noop is not an execinfra.OpNode")
   110  	}
   111  	panic(fmt.Sprintf("invalid index %d", nth))
   112  }