github.com/matrixorigin/matrixone@v1.2.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 "context" 19 gotrace "runtime/trace" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/pb/plan" 25 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" 26 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 27 v2 "github.com/matrixorigin/matrixone/pkg/util/metric/v2" 28 ) 29 30 func runBuildSelectByBinder(stmtType plan.Query_StatementType, ctx CompilerContext, stmt *tree.Select, isPrepareStmt bool) (*Plan, error) { 31 start := time.Now() 32 defer func() { 33 v2.TxnStatementBuildSelectHistogram.Observe(time.Since(start).Seconds()) 34 }() 35 36 builder := NewQueryBuilder(stmtType, ctx, isPrepareStmt) 37 bindCtx := NewBindContext(builder, nil) 38 if IsSnapshotValid(ctx.GetSnapshot()) { 39 bindCtx.snapshot = ctx.GetSnapshot() 40 } 41 42 rootId, err := builder.buildSelect(stmt, bindCtx, true) 43 if err != nil { 44 return nil, err 45 } 46 ctx.SetViews(bindCtx.views) 47 48 builder.qry.Steps = append(builder.qry.Steps, rootId) 49 query, err := builder.createQuery() 50 if err != nil { 51 return nil, err 52 } 53 return &Plan{ 54 Plan: &plan.Plan_Query{ 55 Query: query, 56 }, 57 }, err 58 } 59 60 func buildExplainAnalyze(ctx CompilerContext, stmt *tree.ExplainAnalyze, isPrepareStmt bool) (*Plan, error) { 61 start := time.Now() 62 defer func() { 63 v2.TxnStatementBuildExplainHistogram.Observe(time.Since(start).Seconds()) 64 }() 65 //get query optimizer and execute Optimize 66 plan, err := BuildPlan(ctx, stmt.Statement, isPrepareStmt) 67 if err != nil { 68 return nil, err 69 } 70 //if it is the plan of the EXECUTE, replace it by the plan generated by the PREPARE. 71 //At the same time, replace the param var by the param val 72 if plan.GetDcl() != nil && plan.GetDcl().GetExecute() != nil { 73 execPlan := plan.GetDcl().GetExecute() 74 replaced, _, err := ctx.ReplacePlan(execPlan) 75 if err != nil { 76 return nil, err 77 } 78 plan = replaced 79 } 80 if plan.GetQuery() == nil { 81 return nil, moerr.NewNotSupported(ctx.GetContext(), "the sql query plan does not support explain.") 82 } 83 return plan, nil 84 } 85 86 func BuildPlan(ctx CompilerContext, stmt tree.Statement, isPrepareStmt bool) (*Plan, error) { 87 start := time.Now() 88 defer func() { 89 v2.TxnStatementBuildPlanHistogram.Observe(time.Since(start).Seconds()) 90 }() 91 _, task := gotrace.NewTask(context.TODO(), "plan.BuildPlan") 92 defer task.End() 93 switch stmt := stmt.(type) { 94 case *tree.Select: 95 return runBuildSelectByBinder(plan.Query_SELECT, ctx, stmt, isPrepareStmt) 96 case *tree.ParenSelect: 97 return runBuildSelectByBinder(plan.Query_SELECT, ctx, stmt.Select, isPrepareStmt) 98 case *tree.ExplainAnalyze: 99 return buildExplainAnalyze(ctx, stmt, isPrepareStmt) 100 case *tree.Insert: 101 return buildInsert(stmt, ctx, false, isPrepareStmt) 102 case *tree.Replace: 103 return buildReplace(stmt, ctx, isPrepareStmt) 104 case *tree.Update: 105 return buildTableUpdate(stmt, ctx, isPrepareStmt) 106 case *tree.Delete: 107 return buildDelete(stmt, ctx, isPrepareStmt) 108 case *tree.BeginTransaction: 109 return buildBeginTransaction(stmt, ctx) 110 case *tree.CommitTransaction: 111 return buildCommitTransaction(stmt, ctx) 112 case *tree.RollbackTransaction: 113 return buildRollbackTransaction(stmt, ctx) 114 case *tree.CreateDatabase: 115 return buildCreateDatabase(stmt, ctx) 116 case *tree.DropDatabase: 117 return buildDropDatabase(stmt, ctx) 118 case *tree.CreateTable: 119 return buildCreateTable(stmt, ctx) 120 case *tree.DropTable: 121 return buildDropTable(stmt, ctx) 122 case *tree.TruncateTable: 123 return buildTruncateTable(stmt, ctx) 124 case *tree.CreateSequence: 125 return buildCreateSequence(stmt, ctx) 126 case *tree.DropSequence: 127 return buildDropSequence(stmt, ctx) 128 case *tree.AlterSequence: 129 return buildAlterSequence(stmt, ctx) 130 case *tree.DropView: 131 return buildDropView(stmt, ctx) 132 case *tree.CreateView: 133 return buildCreateView(stmt, ctx) 134 case *tree.CreateSource: 135 return buildCreateSource(stmt, ctx) 136 case *tree.AlterView: 137 return buildAlterView(stmt, ctx) 138 case *tree.AlterTable: 139 return buildAlterTable(stmt, ctx) 140 case *tree.CreateIndex: 141 return buildCreateIndex(stmt, ctx) 142 case *tree.DropIndex: 143 return buildDropIndex(stmt, ctx) 144 case *tree.ShowCreateDatabase: 145 return buildShowCreateDatabase(stmt, ctx) 146 case *tree.ShowCreateTable: 147 return buildShowCreateTable(stmt, ctx) 148 case *tree.ShowCreateView: 149 return buildShowCreateView(stmt, ctx) 150 case *tree.ShowDatabases: 151 return buildShowDatabases(stmt, ctx) 152 case *tree.ShowTables: 153 return buildShowTables(stmt, ctx) 154 case *tree.ShowSequences: 155 return buildShowSequences(stmt, ctx) 156 case *tree.ShowColumns: 157 return buildShowColumns(stmt, ctx) 158 case *tree.ShowTableStatus: 159 return buildShowTableStatus(stmt, ctx) 160 case *tree.ShowTarget: 161 return buildShowTarget(stmt, ctx) 162 case *tree.ShowIndex: 163 return buildShowIndex(stmt, ctx) 164 case *tree.ShowGrants: 165 return buildShowGrants(stmt, ctx) 166 case *tree.ShowVariables: 167 return buildShowVariables(stmt, ctx) 168 case *tree.ShowStatus: 169 return buildShowStatus(stmt, ctx) 170 case *tree.ShowProcessList: 171 return buildShowProcessList(ctx) 172 case *tree.ShowLocks: 173 return buildShowLocks(stmt, ctx) 174 case *tree.ShowNodeList: 175 return buildShowNodeList(stmt, ctx) 176 case *tree.ShowFunctionOrProcedureStatus: 177 return buildShowFunctionOrProcedureStatus(stmt, ctx) 178 case *tree.ShowTableNumber: 179 return buildShowTableNumber(stmt, ctx) 180 case *tree.ShowColumnNumber: 181 return buildShowColumnNumber(stmt, ctx) 182 case *tree.ShowTableValues: 183 return buildShowTableValues(stmt, ctx) 184 case *tree.ShowRolesStmt: 185 return buildShowRoles(stmt, ctx) 186 case *tree.SetVar: 187 return buildSetVariables(stmt, ctx) 188 case *tree.Execute: 189 return buildExecute(stmt, ctx) 190 case *tree.Deallocate: 191 return buildDeallocate(stmt, ctx) 192 case *tree.Load: 193 return buildLoad(stmt, ctx, isPrepareStmt) 194 case *tree.PrepareStmt, *tree.PrepareString: 195 return buildPrepare(stmt, ctx) 196 case *tree.Do, *tree.Declare: 197 return nil, moerr.NewNotSupported(ctx.GetContext(), tree.String(stmt, dialect.MYSQL)) 198 case *tree.ValuesStatement: 199 return buildValues(stmt, ctx, isPrepareStmt) 200 case *tree.LockTableStmt: 201 return buildLockTables(stmt, ctx) 202 case *tree.UnLockTableStmt: 203 return buildUnLockTables(stmt, ctx) 204 case *tree.ShowPublications: 205 return buildShowPublication(stmt, ctx) 206 case *tree.ShowCreatePublications: 207 return buildShowCreatePublications(stmt, ctx) 208 case *tree.ShowStages: 209 return buildShowStages(stmt, ctx) 210 case *tree.ShowSnapShots: 211 return buildShowSnapShots(stmt, ctx) 212 case *tree.CreateAccount: 213 return buildCreateAccount(stmt, ctx, isPrepareStmt) 214 case *tree.AlterAccount: 215 return buildAlterAccount(stmt, ctx, isPrepareStmt) 216 case *tree.DropAccount: 217 return buildDropAccount(stmt, ctx, isPrepareStmt) 218 case *tree.ShowAccountUpgrade: 219 return buildShowAccountUpgrade(stmt, ctx) 220 default: 221 return nil, moerr.NewInternalError(ctx.GetContext(), "statement: '%v'", tree.String(stmt, dialect.MYSQL)) 222 } 223 } 224 225 // GetExecType get executor will execute base AP or TP 226 func GetExecTypeFromPlan(pn *Plan) ExecInfo { 227 defInfo := ExecInfo{ 228 Typ: ExecTypeAP, 229 WithGPU: false, 230 WithBigMem: false, 231 CnNumbers: 2, 232 } 233 if IsTpQuery(pn.GetQuery()) { 234 defInfo.Typ = ExecTypeTP 235 } 236 return defInfo 237 } 238 239 // GetResultColumnsFromPlan 240 func GetResultColumnsFromPlan(p *Plan) []*ColDef { 241 getResultColumnsByProjectionlist := func(query *Query) []*ColDef { 242 lastNode := query.Nodes[query.Steps[len(query.Steps)-1]] 243 columns := make([]*ColDef, len(lastNode.ProjectList)) 244 for idx, expr := range lastNode.ProjectList { 245 columns[idx] = &ColDef{ 246 Name: query.Headings[idx], 247 Typ: expr.Typ, 248 } 249 250 if exprCol, ok := expr.Expr.(*plan.Expr_Col); ok { 251 if col := exprCol.Col; col != nil { 252 columns[idx].TblName = col.TblName 253 columns[idx].DbName = col.DbName 254 } 255 } 256 } 257 258 return columns 259 } 260 261 switch logicPlan := p.Plan.(type) { 262 case *plan.Plan_Query: 263 switch logicPlan.Query.StmtType { 264 case plan.Query_SELECT: 265 return getResultColumnsByProjectionlist(logicPlan.Query) 266 default: 267 // insert/update/delete statement will return nil 268 return nil 269 } 270 case *plan.Plan_Tcl: 271 // begin/commmit/rollback statement will return nil 272 return nil 273 case *plan.Plan_Ddl: 274 switch logicPlan.Ddl.DdlType { 275 case plan.DataDefinition_SHOW_VARIABLES: 276 typ := plan.Type{ 277 Id: int32(types.T_varchar), 278 Width: 1024, 279 } 280 return []*ColDef{ 281 {Typ: typ, Name: "Variable_name"}, 282 {Typ: typ, Name: "Value"}, 283 } 284 default: 285 // show statement(except show variables) will return a query 286 if logicPlan.Ddl.Query != nil { 287 return getResultColumnsByProjectionlist(logicPlan.Ddl.Query) 288 } 289 return nil 290 } 291 } 292 return nil 293 }