github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/build.go (about) 1 // Copyright 2021 - 2022 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 plan 16 17 import ( 18 "github.com/matrixorigin/matrixone/pkg/common/moerr" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/pb/plan" 21 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" 22 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 23 ) 24 25 func runBuildSelectByBinder(stmtType plan.Query_StatementType, ctx CompilerContext, stmt *tree.Select) (*Plan, error) { 26 builder := NewQueryBuilder(stmtType, ctx) 27 bindCtx := NewBindContext(builder, nil) 28 rootId, err := builder.buildSelect(stmt, bindCtx, true) 29 builder.qry.Steps = append(builder.qry.Steps, rootId) 30 if err != nil { 31 return nil, err 32 } 33 query, err := builder.createQuery() 34 if err != nil { 35 return nil, err 36 } 37 return &Plan{ 38 Plan: &plan.Plan_Query{ 39 Query: query, 40 }, 41 }, err 42 } 43 44 func buildExplainAnalyze(ctx CompilerContext, stmt *tree.ExplainAnalyze) (*Plan, error) { 45 //get query optimizer and execute Optimize 46 plan, err := BuildPlan(ctx, stmt.Statement) 47 if err != nil { 48 return nil, err 49 } 50 if plan.GetQuery() == nil { 51 return nil, moerr.NewNotSupported(ctx.GetContext(), "the sql query plan does not support explain.") 52 } 53 return plan, nil 54 } 55 56 func BuildPlan(ctx CompilerContext, stmt tree.Statement) (*Plan, error) { 57 switch stmt := stmt.(type) { 58 case *tree.Select: 59 return runBuildSelectByBinder(plan.Query_SELECT, ctx, stmt) 60 case *tree.ParenSelect: 61 return runBuildSelectByBinder(plan.Query_SELECT, ctx, stmt.Select) 62 case *tree.ExplainAnalyze: 63 return buildExplainAnalyze(ctx, stmt) 64 case *tree.Insert: 65 return buildInsert(stmt, ctx, false) 66 case *tree.Replace: 67 return buildReplace(stmt, ctx) 68 case *tree.Update: 69 return buildTableUpdate(stmt, ctx) 70 case *tree.Delete: 71 return buildDelete(stmt, ctx) 72 case *tree.BeginTransaction: 73 return buildBeginTransaction(stmt, ctx) 74 case *tree.CommitTransaction: 75 return buildCommitTransaction(stmt, ctx) 76 case *tree.RollbackTransaction: 77 return buildRollbackTransaction(stmt, ctx) 78 case *tree.CreateDatabase: 79 return buildCreateDatabase(stmt, ctx) 80 case *tree.DropDatabase: 81 return buildDropDatabase(stmt, ctx) 82 case *tree.CreateTable: 83 return buildCreateTable(stmt, ctx) 84 case *tree.DropTable: 85 return buildDropTable(stmt, ctx) 86 case *tree.TruncateTable: 87 return buildTruncateTable(stmt, ctx) 88 case *tree.DropView: 89 return buildDropView(stmt, ctx) 90 case *tree.CreateView: 91 return buildCreateView(stmt, ctx) 92 case *tree.AlterView: 93 return buildAlterView(stmt, ctx) 94 case *tree.CreateIndex: 95 return buildCreateIndex(stmt, ctx) 96 case *tree.DropIndex: 97 return buildDropIndex(stmt, ctx) 98 case *tree.ShowCreateDatabase: 99 return buildShowCreateDatabase(stmt, ctx) 100 case *tree.ShowCreateTable: 101 return buildShowCreateTable(stmt, ctx) 102 case *tree.ShowCreateView: 103 return buildShowCreateView(stmt, ctx) 104 case *tree.ShowDatabases: 105 return buildShowDatabases(stmt, ctx) 106 case *tree.ShowTables: 107 return buildShowTables(stmt, ctx) 108 case *tree.ShowColumns: 109 return buildShowColumns(stmt, ctx) 110 case *tree.ShowTableStatus: 111 return buildShowTableStatus(stmt, ctx) 112 case *tree.ShowTarget: 113 return buildShowTarget(stmt, ctx) 114 case *tree.ShowIndex: 115 return buildShowIndex(stmt, ctx) 116 case *tree.ShowGrants: 117 return buildShowGrants(stmt, ctx) 118 case *tree.ShowCollation: 119 return buildShowCollation(stmt, ctx) 120 case *tree.ShowVariables: 121 return buildShowVariables(stmt, ctx) 122 case *tree.ShowStatus: 123 return buildShowStatus(stmt, ctx) 124 case *tree.ShowProcessList: 125 return buildShowProcessList(stmt, ctx) 126 case *tree.ShowLocks: 127 return buildShowLocks(stmt, ctx) 128 case *tree.ShowNodeList: 129 return buildShowNodeList(stmt, ctx) 130 case *tree.ShowFunctionStatus: 131 return buildShowFunctionStatus(stmt, ctx) 132 case *tree.ShowTableNumber: 133 return buildShowTableNumber(stmt, ctx) 134 case *tree.ShowColumnNumber: 135 return buildShowColumnNumber(stmt, ctx) 136 case *tree.ShowTableValues: 137 return buildShowTableValues(stmt, ctx) 138 case *tree.SetVar: 139 return buildSetVariables(stmt, ctx) 140 case *tree.Execute: 141 return buildExecute(stmt, ctx) 142 case *tree.Deallocate: 143 return buildDeallocate(stmt, ctx) 144 case *tree.Load: 145 return buildLoad(stmt, ctx) 146 case *tree.PrepareStmt, *tree.PrepareString: 147 return buildPrepare(stmt, ctx) 148 case *tree.Do, *tree.Declare: 149 return nil, moerr.NewNotSupported(ctx.GetContext(), tree.String(stmt, dialect.MYSQL)) 150 case *tree.ValuesStatement: 151 return buildValues(stmt, ctx) 152 default: 153 return nil, moerr.NewInternalError(ctx.GetContext(), "statement: '%v'", tree.String(stmt, dialect.MYSQL)) 154 } 155 } 156 157 // GetExecType get executor will execute base AP or TP 158 func GetExecTypeFromPlan(pn *Plan) ExecInfo { 159 defInfo := ExecInfo{ 160 Typ: ExecTypeAP, 161 WithGPU: false, 162 WithBigMem: false, 163 CnNumbers: 2, 164 } 165 166 tp := true 167 for _, node := range pn.GetQuery().GetNodes() { 168 stats := node.Stats 169 if stats == nil || stats.Outcnt >= 100 || stats.BlockNum >= 4 { 170 tp = false 171 break 172 } 173 } 174 if tp { 175 defInfo.Typ = ExecTypeTP 176 } 177 178 return defInfo 179 } 180 181 // GetResultColumnsFromPlan 182 func GetResultColumnsFromPlan(p *Plan) []*ColDef { 183 getResultColumnsByProjectionlist := func(query *Query) []*ColDef { 184 lastNode := query.Nodes[query.Steps[len(query.Steps)-1]] 185 columns := make([]*ColDef, len(lastNode.ProjectList)) 186 for idx, expr := range lastNode.ProjectList { 187 columns[idx] = &ColDef{ 188 Name: query.Headings[idx], 189 Typ: expr.Typ, 190 } 191 } 192 193 return columns 194 } 195 196 switch logicPlan := p.Plan.(type) { 197 case *plan.Plan_Query: 198 switch logicPlan.Query.StmtType { 199 case plan.Query_SELECT: 200 return getResultColumnsByProjectionlist(logicPlan.Query) 201 default: 202 // insert/update/delete statement will return nil 203 return nil 204 } 205 case *plan.Plan_Tcl: 206 // begin/commmit/rollback statement will return nil 207 return nil 208 case *plan.Plan_Ddl: 209 switch logicPlan.Ddl.DdlType { 210 case plan.DataDefinition_SHOW_VARIABLES: 211 typ := &plan.Type{ 212 Id: int32(types.T_varchar), 213 Width: 1024, 214 } 215 return []*ColDef{ 216 {Typ: typ, Name: "Variable_name"}, 217 {Typ: typ, Name: "Value"}, 218 } 219 default: 220 // show statement(except show variables) will return a query 221 if logicPlan.Ddl.Query != nil { 222 return getResultColumnsByProjectionlist(logicPlan.Ddl.Query) 223 } 224 return nil 225 } 226 } 227 return nil 228 }