github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/exec/execbuilder/format.go (about)

     1  // Copyright 2019 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 execbuilder
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/sql/opt"
    15  	"github.com/cockroachdb/cockroach/pkg/sql/opt/memo"
    16  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    17  )
    18  
    19  func init() {
    20  	// Install the interceptor that implements the ExprFmtHideScalars functionality.
    21  	memo.ScalarFmtInterceptor = fmtInterceptor
    22  }
    23  
    24  // fmtInterceptor is a function suitable for memo.ScalarFmtInterceptor. It detects
    25  // if an expression tree contains only scalar expressions; if so, it tries to
    26  // execbuild them and print the SQL expressions.
    27  func fmtInterceptor(f *memo.ExprFmtCtx, scalar opt.ScalarExpr) string {
    28  	if !onlyScalars(scalar) {
    29  		return ""
    30  	}
    31  
    32  	// Let the filters node show up; we will apply the code on each filter.
    33  	if scalar.Op() == opt.FiltersOp {
    34  		return ""
    35  	}
    36  
    37  	// Build the scalar expression and format it as a single string.
    38  	bld := New(nil /* factory */, f.Memo, nil /* catalog */, scalar, nil /* evalCtx */)
    39  	md := f.Memo.Metadata()
    40  	ivh := tree.MakeIndexedVarHelper(nil /* container */, md.NumColumns())
    41  	expr, err := bld.BuildScalar(&ivh)
    42  	if err != nil {
    43  		// Not all scalar operators are supported (e.g. Projections).
    44  		return ""
    45  	}
    46  	fmtCtx := tree.NewFmtCtx(tree.FmtSimple)
    47  	fmtCtx.SetIndexedVarFormat(func(ctx *tree.FmtCtx, idx int) {
    48  		ctx.WriteString(f.ColumnString(opt.ColumnID(idx + 1)))
    49  	})
    50  	expr.Format(fmtCtx)
    51  	return fmtCtx.String()
    52  }
    53  
    54  func onlyScalars(expr opt.Expr) bool {
    55  	if !opt.IsScalarOp(expr) {
    56  		return false
    57  	}
    58  	for i, n := 0, expr.ChildCount(); i < n; i++ {
    59  		if !onlyScalars(expr.Child(i)) {
    60  			return false
    61  		}
    62  	}
    63  	return true
    64  }