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 }