github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/rowexec/values.go (about) 1 // Copyright 2017 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/flowinfra" 20 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 21 "github.com/cockroachdb/cockroach/pkg/sql/types" 22 ) 23 24 // valuesProcessor is a processor that has no inputs and generates "pre-canned" 25 // rows. 26 type valuesProcessor struct { 27 execinfra.ProcessorBase 28 29 columns []execinfrapb.DatumInfo 30 data [][]byte 31 // numRows is only guaranteed to be set if there are zero columns (because of 32 // backward compatibility). If it set and there are columns, it matches the 33 // number of rows that are encoded in data. 34 numRows uint64 35 36 sd flowinfra.StreamDecoder 37 rowBuf sqlbase.EncDatumRow 38 } 39 40 var _ execinfra.Processor = &valuesProcessor{} 41 var _ execinfra.RowSource = &valuesProcessor{} 42 var _ execinfra.OpNode = &valuesProcessor{} 43 44 const valuesProcName = "values" 45 46 func newValuesProcessor( 47 flowCtx *execinfra.FlowCtx, 48 processorID int32, 49 spec *execinfrapb.ValuesCoreSpec, 50 post *execinfrapb.PostProcessSpec, 51 output execinfra.RowReceiver, 52 ) (*valuesProcessor, error) { 53 v := &valuesProcessor{ 54 columns: spec.Columns, 55 numRows: spec.NumRows, 56 data: spec.RawBytes, 57 } 58 types := make([]*types.T, len(v.columns)) 59 for i := range v.columns { 60 types[i] = v.columns[i].Type 61 } 62 if err := v.Init( 63 v, post, types, flowCtx, processorID, output, nil /* memMonitor */, execinfra.ProcStateOpts{}, 64 ); err != nil { 65 return nil, err 66 } 67 return v, nil 68 } 69 70 // Start is part of the RowSource interface. 71 func (v *valuesProcessor) Start(ctx context.Context) context.Context { 72 ctx = v.StartInternal(ctx, valuesProcName) 73 74 // Add a bogus header to appease the StreamDecoder, which wants to receive a 75 // header before any data. 76 m := &execinfrapb.ProducerMessage{ 77 Typing: v.columns, 78 Header: &execinfrapb.ProducerHeader{}, 79 } 80 if err := v.sd.AddMessage(ctx, m); err != nil { 81 v.MoveToDraining(err) 82 return ctx 83 } 84 85 v.rowBuf = make(sqlbase.EncDatumRow, len(v.columns)) 86 return ctx 87 } 88 89 // Next is part of the RowSource interface. 90 func (v *valuesProcessor) Next() (sqlbase.EncDatumRow, *execinfrapb.ProducerMetadata) { 91 for v.State == execinfra.StateRunning { 92 row, meta, err := v.sd.GetRow(v.rowBuf) 93 if err != nil { 94 v.MoveToDraining(err) 95 break 96 } 97 98 if meta != nil { 99 return nil, meta 100 } 101 102 if row == nil { 103 // Push a chunk of data to the stream decoder. 104 m := &execinfrapb.ProducerMessage{} 105 if len(v.columns) == 0 { 106 if v.numRows == 0 { 107 v.MoveToDraining(nil /* err */) 108 break 109 } 110 m.Data.NumEmptyRows = int32(v.numRows) 111 v.numRows = 0 112 } else { 113 if len(v.data) == 0 { 114 v.MoveToDraining(nil /* err */) 115 break 116 } 117 m.Data.RawBytes = v.data[0] 118 v.data = v.data[1:] 119 } 120 if err := v.sd.AddMessage(context.TODO(), m); err != nil { 121 v.MoveToDraining(err) 122 break 123 } 124 continue 125 } 126 127 if outRow := v.ProcessRowHelper(row); outRow != nil { 128 return outRow, nil 129 } 130 } 131 return nil, v.DrainHelper() 132 133 } 134 135 // ConsumerClosed is part of the RowSource interface. 136 func (v *valuesProcessor) ConsumerClosed() { 137 // The consumer is done, Next() will not be called again. 138 v.InternalClose() 139 } 140 141 // ChildCount is part of the execinfra.OpNode interface. 142 func (v *valuesProcessor) ChildCount(verbose bool) int { 143 return 0 144 } 145 146 // Child is part of the execinfra.OpNode interface. 147 func (v *valuesProcessor) Child(nth int, verbose bool) execinfra.OpNode { 148 panic(fmt.Sprintf("invalid index %d", nth)) 149 }