github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/parsers/tree/explain.go (about)

     1  // Copyright 2021 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tree
    16  
    17  import (
    18  	"strconv"
    19  	"strings"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/reuse"
    22  )
    23  
    24  func init() {
    25  	reuse.CreatePool[ExplainStmt](
    26  		func() *ExplainStmt { return &ExplainStmt{} },
    27  		func(e *ExplainStmt) { e.reset() },
    28  		reuse.DefaultOptions[ExplainStmt](), //.
    29  	) //WithEnableChecker()
    30  
    31  	reuse.CreatePool[ExplainAnalyze](
    32  		func() *ExplainAnalyze { return &ExplainAnalyze{} },
    33  		func(e *ExplainAnalyze) { e.reset() },
    34  		reuse.DefaultOptions[ExplainAnalyze](), //.
    35  	) //WithEnableChecker()
    36  
    37  	reuse.CreatePool[ExplainFor](
    38  		func() *ExplainFor { return &ExplainFor{} },
    39  		func(e *ExplainFor) { e.reset() },
    40  		reuse.DefaultOptions[ExplainFor](), //.
    41  	) //WithEnableChecker()
    42  
    43  }
    44  
    45  type Explain interface {
    46  	Statement
    47  }
    48  
    49  type explainImpl struct {
    50  	Explain
    51  	Statement Statement
    52  	Format    string
    53  	Options   []OptionElem
    54  }
    55  
    56  func (e *explainImpl) Free() {
    57  }
    58  
    59  // EXPLAIN stmt statement
    60  type ExplainStmt struct {
    61  	explainImpl
    62  }
    63  
    64  func (node *ExplainStmt) Format(ctx *FmtCtx) {
    65  	ctx.WriteString("explain")
    66  	if node.Options != nil && len(node.Options) > 0 {
    67  		ctx.WriteString(" (")
    68  		var temp string
    69  		for _, v := range node.Options {
    70  			temp += v.Name
    71  			if v.Value != "NULL" {
    72  				temp += " " + v.Value
    73  			}
    74  			temp += ","
    75  		}
    76  		ctx.WriteString(temp[:len(temp)-1] + ")")
    77  	}
    78  
    79  	stmt := node.explainImpl.Statement
    80  	switch st := stmt.(type) {
    81  	case *ShowColumns:
    82  		if st.Table != nil {
    83  			ctx.WriteByte(' ')
    84  			st.Table.ToTableName().Format(ctx)
    85  		}
    86  		if st.ColName != nil {
    87  			ctx.WriteByte(' ')
    88  			st.ColName.Format(ctx)
    89  		}
    90  	default:
    91  		if stmt != nil {
    92  			ctx.WriteByte(' ')
    93  			stmt.Format(ctx)
    94  		}
    95  	}
    96  }
    97  
    98  func (node *ExplainStmt) GetStatementType() string { return "Explain" }
    99  func (node *ExplainStmt) GetQueryType() string     { return QueryTypeOth }
   100  
   101  // EXPLAIN FOR CONNECTION statement
   102  
   103  func (node *ExplainStmt) Free() {
   104  	reuse.Free[ExplainStmt](node, nil)
   105  }
   106  
   107  func (node *ExplainStmt) reset() {
   108  	*node = ExplainStmt{}
   109  }
   110  
   111  func (node ExplainStmt) TypeName() string { return "tree.ExplainStmt" }
   112  
   113  func NewExplainStmt(stmt Statement, f string) *ExplainStmt {
   114  	ex := reuse.Alloc[ExplainStmt](nil)
   115  	ex.explainImpl.Statement = stmt
   116  	ex.explainImpl.Format = f
   117  	return ex
   118  }
   119  
   120  // EXPLAIN ANALYZE statement
   121  type ExplainAnalyze struct {
   122  	explainImpl
   123  }
   124  
   125  func (node *ExplainAnalyze) Format(ctx *FmtCtx) {
   126  	ctx.WriteString("explain")
   127  	if node.Options != nil && len(node.Options) > 0 {
   128  		ctx.WriteString(" (")
   129  		var temp string
   130  		for _, v := range node.Options {
   131  			temp += v.Name
   132  			if v.Value != "NULL" {
   133  				temp += " " + v.Value
   134  			}
   135  			temp += ","
   136  		}
   137  		ctx.WriteString(temp[:len(temp)-1] + ")")
   138  	}
   139  
   140  	stmt := node.explainImpl.Statement
   141  	switch st := stmt.(type) {
   142  	case *ShowColumns:
   143  		if st.Table != nil {
   144  			ctx.WriteByte(' ')
   145  			st.Table.ToTableName().Format(ctx)
   146  		}
   147  		if st.ColName != nil {
   148  			ctx.WriteByte(' ')
   149  			st.ColName.Format(ctx)
   150  		}
   151  	default:
   152  		if stmt != nil {
   153  			ctx.WriteByte(' ')
   154  			stmt.Format(ctx)
   155  		}
   156  	}
   157  }
   158  
   159  func (node *ExplainAnalyze) GetStatementType() string { return "Explain Analyze" }
   160  func (node *ExplainAnalyze) GetQueryType() string     { return QueryTypeOth }
   161  
   162  func (node *ExplainAnalyze) Free() {
   163  	reuse.Free[ExplainAnalyze](node, nil)
   164  }
   165  
   166  func (node *ExplainAnalyze) reset() {
   167  	*node = ExplainAnalyze{}
   168  }
   169  
   170  func (node ExplainAnalyze) TypeName() string { return "tree.ExplainAnalyze" }
   171  
   172  func NewExplainAnalyze(stmt Statement, f string) *ExplainAnalyze {
   173  	ex := reuse.Alloc[ExplainAnalyze](nil)
   174  	ex.explainImpl.Statement = stmt
   175  	ex.explainImpl.Format = f
   176  	return ex
   177  }
   178  
   179  // EXPLAIN FOR CONNECTION statement
   180  type ExplainFor struct {
   181  	explainImpl
   182  	ID uint64
   183  }
   184  
   185  func (node *ExplainFor) Format(ctx *FmtCtx) {
   186  	ctx.WriteString("explain format = ")
   187  	ctx.WriteString(node.explainImpl.Format)
   188  	ctx.WriteString(" for connection ")
   189  	ctx.WriteString(strconv.FormatInt(int64(node.ID), 10))
   190  }
   191  
   192  func (node *ExplainFor) GetStatementType() string { return "Explain Format" }
   193  func (node *ExplainFor) GetQueryType() string     { return QueryTypeOth }
   194  
   195  func (node *ExplainFor) Free() {
   196  	reuse.Free[ExplainFor](node, nil)
   197  }
   198  
   199  func (node *ExplainFor) reset() {
   200  	*node = ExplainFor{}
   201  }
   202  
   203  func (node ExplainFor) TypeName() string { return "tree.ExplainFor" }
   204  
   205  func NewExplainFor(f string, id uint64) *ExplainFor {
   206  	ex := reuse.Alloc[ExplainFor](nil)
   207  	ex.explainImpl = explainImpl{Statement: nil, Format: f}
   208  	ex.ID = id
   209  	return ex
   210  }
   211  
   212  type OptionElem struct {
   213  	Name  string
   214  	Value string
   215  }
   216  
   217  func MakeOptionElem(name string, value string) OptionElem {
   218  	return OptionElem{
   219  		Name:  name,
   220  		Value: value,
   221  	}
   222  }
   223  
   224  func MakeOptions(elem OptionElem) []OptionElem {
   225  	var options = make([]OptionElem, 1)
   226  	options[0] = elem
   227  	return options
   228  }
   229  
   230  func IsContainAnalyze(options []OptionElem) bool {
   231  	if len(options) > 0 {
   232  		for _, option := range options {
   233  			if strings.EqualFold(option.Name, "analyze") && strings.EqualFold(option.Value, "true") {
   234  				return true
   235  			}
   236  		}
   237  	}
   238  	return false
   239  }