github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/execinfrapb/data.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 execinfrapb 12 13 import ( 14 "context" 15 "fmt" 16 "sync" 17 18 "github.com/cockroachdb/cockroach/pkg/keys" 19 "github.com/cockroachdb/cockroach/pkg/kv" 20 "github.com/cockroachdb/cockroach/pkg/roachpb" 21 "github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver" 22 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 23 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 24 "github.com/cockroachdb/cockroach/pkg/sql/types" 25 "github.com/cockroachdb/cockroach/pkg/util/encoding" 26 "github.com/cockroachdb/cockroach/pkg/util/tracing" 27 "github.com/cockroachdb/errors" 28 "github.com/cockroachdb/logtags" 29 ) 30 31 // ConvertToColumnOrdering converts an Ordering type (as defined in data.proto) 32 // to a sqlbase.ColumnOrdering type. 33 func ConvertToColumnOrdering(specOrdering Ordering) sqlbase.ColumnOrdering { 34 ordering := make(sqlbase.ColumnOrdering, len(specOrdering.Columns)) 35 for i, c := range specOrdering.Columns { 36 ordering[i].ColIdx = int(c.ColIdx) 37 if c.Direction == Ordering_Column_ASC { 38 ordering[i].Direction = encoding.Ascending 39 } else { 40 ordering[i].Direction = encoding.Descending 41 } 42 } 43 return ordering 44 } 45 46 // ConvertToSpecOrdering converts a sqlbase.ColumnOrdering type 47 // to an Ordering type (as defined in data.proto). 48 func ConvertToSpecOrdering(columnOrdering sqlbase.ColumnOrdering) Ordering { 49 return ConvertToMappedSpecOrdering(columnOrdering, nil) 50 } 51 52 // ConvertToMappedSpecOrdering converts a sqlbase.ColumnOrdering type 53 // to an Ordering type (as defined in data.proto), using the column 54 // indices contained in planToStreamColMap. 55 func ConvertToMappedSpecOrdering( 56 columnOrdering sqlbase.ColumnOrdering, planToStreamColMap []int, 57 ) Ordering { 58 specOrdering := Ordering{} 59 specOrdering.Columns = make([]Ordering_Column, len(columnOrdering)) 60 for i, c := range columnOrdering { 61 colIdx := c.ColIdx 62 if planToStreamColMap != nil { 63 colIdx = planToStreamColMap[c.ColIdx] 64 if colIdx == -1 { 65 panic(fmt.Sprintf("column %d in sort ordering not available", c.ColIdx)) 66 } 67 } 68 specOrdering.Columns[i].ColIdx = uint32(colIdx) 69 if c.Direction == encoding.Ascending { 70 specOrdering.Columns[i].Direction = Ordering_Column_ASC 71 } else { 72 specOrdering.Columns[i].Direction = Ordering_Column_DESC 73 } 74 } 75 return specOrdering 76 } 77 78 // DistSQLTypeResolver implements tree.ResolvableTypeReference for accessing 79 // type information during DistSQL query evaluation. 80 type DistSQLTypeResolver struct { 81 EvalContext *tree.EvalContext 82 // TODO (rohany): This struct should locally cache id -> types.T here 83 // so that repeated lookups do not incur additional KV operations. 84 } 85 86 // ResolveType implements tree.ResolvableTypeReference. 87 func (tr *DistSQLTypeResolver) ResolveType( 88 context.Context, *tree.UnresolvedObjectName, 89 ) (*types.T, error) { 90 return nil, errors.AssertionFailedf("cannot resolve types in DistSQL by name") 91 } 92 93 func makeTypeLookupFunc( 94 ctx context.Context, txn *kv.Txn, codec keys.SQLCodec, 95 ) sqlbase.TypeLookupFunc { 96 return func(id sqlbase.ID) (*tree.TypeName, *sqlbase.TypeDescriptor, error) { 97 return resolver.ResolveTypeDescByID(ctx, txn, codec, id) 98 } 99 } 100 101 // ResolveTypeByID implements tree.ResolvableTypeReference. 102 func (tr *DistSQLTypeResolver) ResolveTypeByID(ctx context.Context, id uint32) (*types.T, error) { 103 // TODO (rohany): This should eventually look into the set of cached type 104 // descriptors before attempting to access it here. 105 lookup := makeTypeLookupFunc(ctx, tr.EvalContext.Txn, tr.EvalContext.Codec) 106 name, typDesc, err := lookup(sqlbase.ID(id)) 107 if err != nil { 108 return nil, err 109 } 110 return typDesc.MakeTypesT(name, lookup) 111 } 112 113 // HydrateTypeSlice hydrates all user defined types in an input slice of types. 114 func HydrateTypeSlice(evalCtx *tree.EvalContext, typs []*types.T) error { 115 // TODO (rohany): This should eventually look into the set of cached type 116 // descriptors before attempting to access it here. 117 lookup := makeTypeLookupFunc(evalCtx.Context, evalCtx.Txn, evalCtx.Codec) 118 for _, t := range typs { 119 if t.UserDefined() { 120 name, typDesc, err := lookup(sqlbase.ID(t.StableTypeID())) 121 if err != nil { 122 return err 123 } 124 if err := typDesc.HydrateTypeInfoWithName(t, name, lookup); err != nil { 125 return err 126 } 127 } 128 } 129 return nil 130 } 131 132 // ExprFmtCtxBase produces a FmtCtx used for serializing expressions; a proper 133 // IndexedVar formatting function needs to be added on. It replaces placeholders 134 // with their values. 135 func ExprFmtCtxBase(evalCtx *tree.EvalContext) *tree.FmtCtx { 136 fmtCtx := tree.NewFmtCtx(tree.FmtCheckEquivalence) 137 fmtCtx.SetPlaceholderFormat( 138 func(fmtCtx *tree.FmtCtx, p *tree.Placeholder) { 139 d, err := p.Eval(evalCtx) 140 if err != nil { 141 panic(fmt.Sprintf("failed to serialize placeholder: %s", err)) 142 } 143 d.Format(fmtCtx) 144 }) 145 return fmtCtx 146 } 147 148 // Expression is the representation of a SQL expression. 149 // See data.proto for the corresponding proto definition. Its automatic type 150 // declaration is suppressed in the proto via the typedecl=false option, so that 151 // we can add the LocalExpr field which is not serialized. It never needs to be 152 // serialized because we only use it in the case where we know we won't need to 153 // send it, as a proto, to another machine. 154 type Expression struct { 155 // Version is unused. 156 Version string 157 158 // Expr, if present, is the string representation of this expression. 159 // SQL expressions are passed as a string, with ordinal references 160 // (@1, @2, @3 ..) used for "input" variables. 161 Expr string 162 163 // LocalExpr is an unserialized field that's used to pass expressions to local 164 // flows without serializing/deserializing them. 165 LocalExpr tree.TypedExpr 166 } 167 168 // Empty returns true if the expression has neither an Expr nor LocalExpr. 169 func (e *Expression) Empty() bool { 170 return e.Expr == "" && e.LocalExpr == nil 171 } 172 173 // String implements the Stringer interface. 174 func (e Expression) String() string { 175 if e.LocalExpr != nil { 176 ctx := tree.NewFmtCtx(tree.FmtCheckEquivalence) 177 ctx.FormatNode(e.LocalExpr) 178 return ctx.CloseAndGetString() 179 } 180 if e.Expr != "" { 181 return e.Expr 182 } 183 return "none" 184 } 185 186 // String implements fmt.Stringer. 187 func (e *Error) String() string { 188 if err := e.ErrorDetail(context.TODO()); err != nil { 189 return err.Error() 190 } 191 return "<nil>" 192 } 193 194 // NewError creates an Error from an error, to be sent on the wire. It will 195 // recognize certain errors and marshall them accordingly, and everything 196 // unrecognized is turned into a PGError with code "internal". 197 func NewError(ctx context.Context, err error) *Error { 198 resErr := &Error{} 199 200 // Encode the full error to the best of our ability. 201 // This field is ignored by 19.1 nodes and prior. 202 ctx = logtags.AddTag(ctx, "sent-error", nil) 203 fullError := errors.EncodeError(ctx, errors.WithContextTags(err, ctx)) 204 resErr.FullError = &fullError 205 206 return resErr 207 } 208 209 // ErrorDetail returns the payload as a Go error. 210 func (e *Error) ErrorDetail(ctx context.Context) (err error) { 211 if e == nil { 212 return nil 213 } 214 defer func() { 215 ctx = logtags.AddTag(ctx, "received-error", nil) 216 err = errors.WithContextTags(err, ctx) 217 }() 218 219 if e.FullError != nil { 220 // If there's a 19.2-forward full error, decode and use that. 221 // This will reveal a fully causable detailed error structure. 222 return errors.DecodeError(ctx, *e.FullError) 223 } 224 225 // We're receiving an error we don't know about. It's all right, 226 // it's still an error, just one we didn't expect. Let it go 227 // through. We'll pick it up in reporting. 228 return errors.AssertionFailedf("unknown error from remote node") 229 } 230 231 // ProducerMetadata represents a metadata record flowing through a DistSQL flow. 232 type ProducerMetadata struct { 233 // Only one of these fields will be set. If this ever changes, note that 234 // there're consumers out there that extract the error and, if there is one, 235 // forward it in isolation and drop the rest of the record. 236 Ranges []roachpb.RangeInfo 237 // TODO(vivek): change to type Error 238 Err error 239 // TraceData is sent if snowball tracing is enabled. 240 TraceData []tracing.RecordedSpan 241 // LeafTxnFinalState contains the final state of the LeafTxn to be 242 // sent from leaf flows to the RootTxn held by the flow's ultimate 243 // receiver. 244 LeafTxnFinalState *roachpb.LeafTxnFinalState 245 // RowNum corresponds to a row produced by a "source" processor that takes no 246 // inputs. It is used in tests to verify that all metadata is forwarded 247 // exactly once to the receiver on the gateway node. 248 RowNum *RemoteProducerMetadata_RowNum 249 // SamplerProgress contains incremental progress information from the sampler 250 // processor. 251 SamplerProgress *RemoteProducerMetadata_SamplerProgress 252 // BulkProcessorProgress contains incremental progress information from a bulk 253 // operation processor (backfiller, import, etc). 254 BulkProcessorProgress *RemoteProducerMetadata_BulkProcessorProgress 255 // Metrics contains information about goodput of the node. 256 Metrics *RemoteProducerMetadata_Metrics 257 } 258 259 var ( 260 // TODO(yuzefovich): use this pool in other places apart from metrics 261 // collection. 262 // producerMetadataPool is a pool of producer metadata objects. 263 producerMetadataPool = sync.Pool{ 264 New: func() interface{} { 265 return &ProducerMetadata{} 266 }, 267 } 268 269 // rpmMetricsPool is a pool of metadata used to propagate metrics. 270 rpmMetricsPool = sync.Pool{ 271 New: func() interface{} { 272 return &RemoteProducerMetadata_Metrics{} 273 }, 274 } 275 ) 276 277 // Release is part of Releasable interface. 278 func (meta *ProducerMetadata) Release() { 279 *meta = ProducerMetadata{} 280 producerMetadataPool.Put(meta) 281 } 282 283 // Release is part of Releasable interface. Note that although this meta is 284 // only used together with a ProducerMetadata that comes from another pool, we 285 // do not combine two Release methods into one because two objects have a 286 // different lifetime. 287 func (meta *RemoteProducerMetadata_Metrics) Release() { 288 *meta = RemoteProducerMetadata_Metrics{} 289 rpmMetricsPool.Put(meta) 290 } 291 292 // GetProducerMeta returns a producer metadata object from the pool. 293 func GetProducerMeta() *ProducerMetadata { 294 return producerMetadataPool.Get().(*ProducerMetadata) 295 } 296 297 // GetMetricsMeta returns a metadata object from the pool of metrics metadata. 298 func GetMetricsMeta() *RemoteProducerMetadata_Metrics { 299 return rpmMetricsPool.Get().(*RemoteProducerMetadata_Metrics) 300 } 301 302 // RemoteProducerMetaToLocalMeta converts a RemoteProducerMetadata struct to 303 // ProducerMetadata and returns whether the conversion was successful or not. 304 func RemoteProducerMetaToLocalMeta( 305 ctx context.Context, rpm RemoteProducerMetadata, 306 ) (ProducerMetadata, bool) { 307 meta := GetProducerMeta() 308 switch v := rpm.Value.(type) { 309 case *RemoteProducerMetadata_RangeInfo: 310 meta.Ranges = v.RangeInfo.RangeInfo 311 case *RemoteProducerMetadata_TraceData_: 312 meta.TraceData = v.TraceData.CollectedSpans 313 case *RemoteProducerMetadata_LeafTxnFinalState: 314 meta.LeafTxnFinalState = v.LeafTxnFinalState 315 case *RemoteProducerMetadata_RowNum_: 316 meta.RowNum = v.RowNum 317 case *RemoteProducerMetadata_SamplerProgress_: 318 meta.SamplerProgress = v.SamplerProgress 319 case *RemoteProducerMetadata_BulkProcessorProgress_: 320 meta.BulkProcessorProgress = v.BulkProcessorProgress 321 case *RemoteProducerMetadata_Error: 322 meta.Err = v.Error.ErrorDetail(ctx) 323 case *RemoteProducerMetadata_Metrics_: 324 meta.Metrics = v.Metrics 325 default: 326 return *meta, false 327 } 328 return *meta, true 329 } 330 331 // LocalMetaToRemoteProducerMeta converts a ProducerMetadata struct to 332 // RemoteProducerMetadata. 333 func LocalMetaToRemoteProducerMeta( 334 ctx context.Context, meta ProducerMetadata, 335 ) RemoteProducerMetadata { 336 var rpm RemoteProducerMetadata 337 if meta.Ranges != nil { 338 rpm.Value = &RemoteProducerMetadata_RangeInfo{ 339 RangeInfo: &RemoteProducerMetadata_RangeInfos{ 340 RangeInfo: meta.Ranges, 341 }, 342 } 343 } else if meta.TraceData != nil { 344 rpm.Value = &RemoteProducerMetadata_TraceData_{ 345 TraceData: &RemoteProducerMetadata_TraceData{ 346 CollectedSpans: meta.TraceData, 347 }, 348 } 349 } else if meta.LeafTxnFinalState != nil { 350 rpm.Value = &RemoteProducerMetadata_LeafTxnFinalState{ 351 LeafTxnFinalState: meta.LeafTxnFinalState, 352 } 353 } else if meta.RowNum != nil { 354 rpm.Value = &RemoteProducerMetadata_RowNum_{ 355 RowNum: meta.RowNum, 356 } 357 } else if meta.SamplerProgress != nil { 358 rpm.Value = &RemoteProducerMetadata_SamplerProgress_{ 359 SamplerProgress: meta.SamplerProgress, 360 } 361 } else if meta.BulkProcessorProgress != nil { 362 rpm.Value = &RemoteProducerMetadata_BulkProcessorProgress_{ 363 BulkProcessorProgress: meta.BulkProcessorProgress, 364 } 365 } else if meta.Metrics != nil { 366 rpm.Value = &RemoteProducerMetadata_Metrics_{ 367 Metrics: meta.Metrics, 368 } 369 } else { 370 rpm.Value = &RemoteProducerMetadata_Error{ 371 Error: NewError(ctx, meta.Err), 372 } 373 } 374 return rpm 375 } 376 377 // MetadataSource is an interface implemented by processors and columnar 378 // operators that can produce metadata. 379 type MetadataSource interface { 380 // DrainMeta returns all the metadata produced by the processor or operator. 381 // It will be called exactly once, usually, when the processor or operator 382 // has finished doing its computations. 383 // Implementers can choose what to do on subsequent calls (if such occur). 384 // TODO(yuzefovich): modify the contract to require returning nil on all 385 // calls after the first one. 386 DrainMeta(context.Context) []ProducerMetadata 387 }