From 1fd13c93e969e3c4cf50ac2818af657e81dd9d24 Mon Sep 17 00:00:00 2001 From: Rebecca Taft Date: Wed, 23 Jun 2021 15:23:58 -0500 Subject: [PATCH] opt: fix panic due to concurrent map writes when copying metadata This commit fixes a bug that caused a panic due to concurrent map writes when copying table metadata. The fix is to make a deep copy of the map before updating it. Fixes #66717 Release note (bug fix): Fixed a panic that could occur in the optimizer when executing a prepared plan with placeholders. This could happen when one of the tables used by the query had computed columns or a partial index. --- pkg/sql/opt/table_meta.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/sql/opt/table_meta.go b/pkg/sql/opt/table_meta.go index 38e13ede0ad3..a7f25988c8fb 100644 --- a/pkg/sql/opt/table_meta.go +++ b/pkg/sql/opt/table_meta.go @@ -186,11 +186,21 @@ func (tm *TableMeta) copyScalars(copyScalar func(Expr) Expr) { if tm.Constraints != nil { tm.Constraints = copyScalar(tm.Constraints).(ScalarExpr) } - for col, e := range tm.ComputedCols { - tm.ComputedCols[col] = copyScalar(e).(ScalarExpr) + + if tm.ComputedCols != nil { + computedCols := make(map[ColumnID]ScalarExpr, len(tm.ComputedCols)) + for col, e := range tm.ComputedCols { + computedCols[col] = copyScalar(e).(ScalarExpr) + } + tm.ComputedCols = computedCols } - for idx, e := range tm.partialIndexPredicates { - tm.partialIndexPredicates[idx] = copyScalar(e).(ScalarExpr) + + if tm.partialIndexPredicates != nil { + partialIndexPredicates := make(map[cat.IndexOrdinal]ScalarExpr, len(tm.partialIndexPredicates)) + for idx, e := range tm.partialIndexPredicates { + partialIndexPredicates[idx] = copyScalar(e).(ScalarExpr) + } + tm.partialIndexPredicates = partialIndexPredicates } }