github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/explain.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"bytes"
    18  	"fmt"
    19  	"sort"
    20  	"strings"
    21  
    22  	"github.com/whtcorpsinc/milevadb/types"
    23  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    24  )
    25  
    26  // ExplainInfo implements the Expression interface.
    27  func (expr *ScalarFunction) ExplainInfo() string {
    28  	return expr.explainInfo(false)
    29  }
    30  
    31  func (expr *ScalarFunction) explainInfo(normalized bool) string {
    32  	var buffer bytes.Buffer
    33  	fmt.Fprintf(&buffer, "%s(", expr.FuncName.L)
    34  	for i, arg := range expr.GetArgs() {
    35  		if normalized {
    36  			buffer.WriteString(arg.ExplainNormalizedInfo())
    37  		} else {
    38  			buffer.WriteString(arg.ExplainInfo())
    39  		}
    40  		if i+1 < len(expr.GetArgs()) {
    41  			buffer.WriteString(", ")
    42  		}
    43  	}
    44  	buffer.WriteString(")")
    45  	return buffer.String()
    46  }
    47  
    48  // ExplainNormalizedInfo implements the Expression interface.
    49  func (expr *ScalarFunction) ExplainNormalizedInfo() string {
    50  	return expr.explainInfo(true)
    51  }
    52  
    53  // ExplainInfo implements the Expression interface.
    54  func (defCaus *DeferredCauset) ExplainInfo() string {
    55  	return defCaus.String()
    56  }
    57  
    58  // ExplainNormalizedInfo implements the Expression interface.
    59  func (defCaus *DeferredCauset) ExplainNormalizedInfo() string {
    60  	if defCaus.OrigName != "" {
    61  		return defCaus.OrigName
    62  	}
    63  	return "?"
    64  }
    65  
    66  // ExplainInfo implements the Expression interface.
    67  func (expr *Constant) ExplainInfo() string {
    68  	dt, err := expr.Eval(chunk.Event{})
    69  	if err != nil {
    70  		return "not recognized const vanue"
    71  	}
    72  	return expr.format(dt)
    73  }
    74  
    75  // ExplainNormalizedInfo implements the Expression interface.
    76  func (expr *Constant) ExplainNormalizedInfo() string {
    77  	return "?"
    78  }
    79  
    80  func (expr *Constant) format(dt types.Causet) string {
    81  	switch dt.HoTT() {
    82  	case types.HoTTNull:
    83  		return "NULL"
    84  	case types.HoTTString, types.HoTTBytes, types.HoTTMysqlEnum, types.HoTTMysqlSet,
    85  		types.HoTTMysqlJSON, types.HoTTBinaryLiteral, types.HoTTMysqlBit:
    86  		return fmt.Sprintf("\"%v\"", dt.GetValue())
    87  	}
    88  	return fmt.Sprintf("%v", dt.GetValue())
    89  }
    90  
    91  // ExplainExpressionList generates explain information for a list of memexs.
    92  func ExplainExpressionList(exprs []Expression, schemaReplicant *Schema) string {
    93  	builder := &strings.Builder{}
    94  	for i, expr := range exprs {
    95  		switch expr.(type) {
    96  		case *DeferredCauset, *CorrelatedDeferredCauset:
    97  			builder.WriteString(expr.String())
    98  		default:
    99  			builder.WriteString(expr.String())
   100  			builder.WriteString("->")
   101  			builder.WriteString(schemaReplicant.DeferredCausets[i].String())
   102  		}
   103  		if i+1 < len(exprs) {
   104  			builder.WriteString(", ")
   105  		}
   106  	}
   107  	return builder.String()
   108  }
   109  
   110  // SortedExplainExpressionList generates explain information for a list of memexs in order.
   111  // In some scenarios, the expr's order may not be sblock when executing multiple times.
   112  // So we add a sort to make its explain result sblock.
   113  func SortedExplainExpressionList(exprs []Expression) []byte {
   114  	return sortedExplainExpressionList(exprs, false)
   115  }
   116  
   117  func sortedExplainExpressionList(exprs []Expression, normalized bool) []byte {
   118  	buffer := bytes.NewBufferString("")
   119  	exprInfos := make([]string, 0, len(exprs))
   120  	for _, expr := range exprs {
   121  		if normalized {
   122  			exprInfos = append(exprInfos, expr.ExplainNormalizedInfo())
   123  		} else {
   124  			exprInfos = append(exprInfos, expr.ExplainInfo())
   125  		}
   126  	}
   127  	sort.Strings(exprInfos)
   128  	for i, info := range exprInfos {
   129  		buffer.WriteString(info)
   130  		if i+1 < len(exprInfos) {
   131  			buffer.WriteString(", ")
   132  		}
   133  	}
   134  	return buffer.Bytes()
   135  }
   136  
   137  // SortedExplainNormalizedExpressionList is same like SortedExplainExpressionList, but use for generating normalized information.
   138  func SortedExplainNormalizedExpressionList(exprs []Expression) []byte {
   139  	return sortedExplainExpressionList(exprs, true)
   140  }
   141  
   142  // SortedExplainNormalizedScalarFuncList is same like SortedExplainExpressionList, but use for generating normalized information.
   143  func SortedExplainNormalizedScalarFuncList(exprs []*ScalarFunction) []byte {
   144  	memexs := make([]Expression, len(exprs))
   145  	for i := range exprs {
   146  		memexs[i] = exprs[i]
   147  	}
   148  	return sortedExplainExpressionList(memexs, true)
   149  }
   150  
   151  // ExplainDeferredCausetList generates explain information for a list of defCausumns.
   152  func ExplainDeferredCausetList(defcaus []*DeferredCauset) []byte {
   153  	buffer := bytes.NewBufferString("")
   154  	for i, defCaus := range defcaus {
   155  		buffer.WriteString(defCaus.ExplainInfo())
   156  		if i+1 < len(defcaus) {
   157  			buffer.WriteString(", ")
   158  		}
   159  	}
   160  	return buffer.Bytes()
   161  }