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 }