func mockResolve(node ast.Node) { indices := []*model.IndexInfo{ { Name: model.NewCIStr("b"), Columns: []*model.IndexColumn{ { Name: model.NewCIStr("b"), }, }, }, { Name: model.NewCIStr("c_d"), Columns: []*model.IndexColumn{ { Name: model.NewCIStr("c"), }, { Name: model.NewCIStr("d"), }, }, }, } pkColumn := &model.ColumnInfo{ Name: model.NewCIStr("a"), } pkColumn.Flag = mysql.PriKeyFlag table := &model.TableInfo{ Columns: []*model.ColumnInfo{pkColumn}, Indices: indices, Name: model.NewCIStr("t"), PKIsHandle: true, } resolver := mockResolver{table: table} node.Accept(&resolver) }
// InferType infers result type for ast.ExprNode. func InferType(node ast.Node) error { var inferrer typeInferrer // TODO: get the default charset from ctx inferrer.defaultCharset = "utf8" node.Accept(&inferrer) return inferrer.err }
// mockJoinResolve resolves multi talbe and column name for join statement. func mockJoinResolve(c *C, node ast.Node) { resolver := &mockJoinResolver{ c: c, tables: map[string]*ast.TableName{}, refers: map[*model.ColumnInfo]*ast.ResultField{}, } node.Accept(resolver) }
// InferType infers result type for ast.ExprNode. func InferType(sc *variable.StatementContext, node ast.Node) error { var inferrer typeInferrer inferrer.sc = sc // TODO: get the default charset from ctx inferrer.defaultCharset = "utf8" node.Accept(&inferrer) return inferrer.err }
func (b *planBuilder) buildSubquery(n ast.Node) { sv := &subqueryVisitor{ builder: b, } _, ok := n.Accept(sv) if !ok { log.Errorf("Extract subquery error") } }
// IsSupported checks if the node is supported to use new plan. // We first support single table select statement without group by clause or aggregate functions. // TODO: 1. insert/update/delete. 2. join tables. 3. subquery. 4. group by and aggregate function. func IsSupported(node ast.Node) bool { switch node.(type) { case *ast.SelectStmt, *ast.PrepareStmt, *ast.ExecuteStmt, *ast.DeallocateStmt: default: return false } var checker supportChecker node.Accept(&checker) return !checker.unsupported }
// Validate checkes whether the node is valid. func Validate(node ast.Node, inPrepare bool) error { v := validator{inPrepare: inPrepare} node.Accept(&v) return v.err }
// preEvaluate evaluates preEvaluable expression and rewrites constant expression to value expression. func preEvaluate(ctx context.Context, node ast.Node) error { pe := preEvaluator{ctx: ctx} node.Accept(&pe) return pe.err }
// ResolveName resolves table name and column name. // It generates ResultFields for ResultSetNode and resolves ColumnNameExpr to a ResultField. func ResolveName(node ast.Node, info infoschema.InfoSchema, ctx context.Context) error { defaultSchema := db.GetCurrentSchema(ctx) resolver := nameResolver{Info: info, Ctx: ctx, DefaultSchema: model.NewCIStr(defaultSchema)} node.Accept(&resolver) return errors.Trace(resolver.Err) }
// MockResolveName only serves for test. func MockResolveName(node ast.Node, info infoschema.InfoSchema, defaultSchema string, ctx context.Context) error { resolver := nameResolver{Info: info, Ctx: ctx, DefaultSchema: model.NewCIStr(defaultSchema)} node.Accept(&resolver) return resolver.Err }
// InferType infers result type for ast.ExprNode. func InferType(node ast.Node) error { var inferrer typeInferrer node.Accept(&inferrer) return inferrer.err }
// Compile compiles a ast.Node into an executable statement. func (com *Compiler) Compile(node ast.Node) (stmt.Statement, error) { validator := &validator{} if _, ok := node.Accept(validator); !ok { return nil, errors.Trace(validator.err) } // binder := &InfoBinder{} // if _, ok := node.Accept(validator); !ok { // return nil, errors.Trace(binder.Err) // } tpComputer := &typeComputer{} if _, ok := node.Accept(tpComputer); !ok { return nil, errors.Trace(tpComputer.err) } c := newExpressionConverter() com.converter = c switch v := node.(type) { case *ast.InsertStmt: return convertInsert(c, v) case *ast.DeleteStmt: return convertDelete(c, v) case *ast.UpdateStmt: return convertUpdate(c, v) case *ast.SelectStmt: return convertSelect(c, v) case *ast.UnionStmt: return convertUnion(c, v) case *ast.CreateDatabaseStmt: return convertCreateDatabase(c, v) case *ast.DropDatabaseStmt: return convertDropDatabase(c, v) case *ast.CreateTableStmt: return convertCreateTable(c, v) case *ast.DropTableStmt: return convertDropTable(c, v) case *ast.CreateIndexStmt: return convertCreateIndex(c, v) case *ast.DropIndexStmt: return convertDropIndex(c, v) case *ast.AlterTableStmt: return convertAlterTable(c, v) case *ast.TruncateTableStmt: return convertTruncateTable(c, v) case *ast.ExplainStmt: return convertExplain(c, v) case *ast.PrepareStmt: return convertPrepare(c, v) case *ast.DeallocateStmt: return convertDeallocate(c, v) case *ast.ExecuteStmt: return convertExecute(c, v) case *ast.ShowStmt: return convertShow(c, v) case *ast.BeginStmt: return convertBegin(c, v) case *ast.CommitStmt: return convertCommit(c, v) case *ast.RollbackStmt: return convertRollback(c, v) case *ast.UseStmt: return convertUse(c, v) case *ast.SetStmt: return convertSet(c, v) case *ast.SetCharsetStmt: return convertSetCharset(c, v) case *ast.SetPwdStmt: return convertSetPwd(c, v) case *ast.CreateUserStmt: return convertCreateUser(c, v) case *ast.DoStmt: return convertDo(c, v) case *ast.GrantStmt: return convertGrant(c, v) } return nil, nil }