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  }