From c312799c72d8e4fb4c27da1551a55a530fdf8dc5 Mon Sep 17 00:00:00 2001 From: Yahor Yuzefovich Date: Mon, 22 Mar 2021 13:43:00 -0700 Subject: [PATCH] colbuilder: minor optimization of removing redundant allocations At the end of `NewColOperator` call we have to enforce that the result column type schema is as expected. We do so by comparing the actual and the expected types and planning casts if needed with a simple project op to remove the leftovers. Previously, we would always allocate a uint32 slice for the projection and a types slice in `addProjection`, regardless of the fact whether projection is redundant or not (note that in `NewSimpleProjectOp` we would end up returning the original operator). This is unnecessary in most cases, so we now delay the allocation of the projection slice until we find the first column that needs a cast. Release note: None --- pkg/sql/colexec/colbuilder/execplan.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/pkg/sql/colexec/colbuilder/execplan.go b/pkg/sql/colexec/colbuilder/execplan.go index 0d39bf04d0a1..b12660c29d5c 100644 --- a/pkg/sql/colexec/colbuilder/execplan.go +++ b/pkg/sql/colexec/colbuilder/execplan.go @@ -1319,7 +1319,9 @@ func NewColOperator( if len(args.Spec.ResultTypes) != len(r.ColumnTypes) { return r, errors.AssertionFailedf("unexpectedly different number of columns are output: expected %v, actual %v", args.Spec.ResultTypes, r.ColumnTypes) } - projection := make([]uint32, len(args.Spec.ResultTypes)) + // projection is lazily allocated when the first column that needs an + // explicit cast is found. It'll remain nil if projection isn't necessary. + var projection []uint32 for i := range args.Spec.ResultTypes { expected, actual := args.Spec.ResultTypes[i], r.ColumnTypes[i] if !actual.Identical(expected) { @@ -1347,12 +1349,23 @@ func NewColOperator( } } r.ColumnTypes = resultTypes + if projection == nil { + // This is the first column that needs an explicit cast, so we + // need to actually allocate the slice and set all previous + // columns to be used as is. + projection = make([]uint32, len(args.Spec.ResultTypes)) + for j := 0; j < i; j++ { + projection[j] = uint32(j) + } + } projection[i] = uint32(castedIdx) - } else { + } else if projection != nil { projection[i] = uint32(i) } } - r.Op, r.ColumnTypes = addProjection(r.Op, r.ColumnTypes, projection) + if projection != nil { + r.Op, r.ColumnTypes = addProjection(r.Op, r.ColumnTypes, projection) + } if args.TestingKnobs.PlanInvariantsCheckers { r.Op = colexec.NewInvariantsChecker(r.Op) }