github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/executor/builder.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 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 executor 16 17 import ( 18 "github.com/pingcap/errors" 19 "github.com/vescale/zgraph/codec" 20 "github.com/vescale/zgraph/parser/ast" 21 "github.com/vescale/zgraph/planner" 22 "github.com/vescale/zgraph/stmtctx" 23 ) 24 25 // Builder is used to build from a plan into executor. 26 type Builder struct { 27 sc *stmtctx.Context 28 err error 29 } 30 31 // NewBuilder returns a build instance. 32 func NewBuilder(sc *stmtctx.Context) *Builder { 33 return &Builder{ 34 sc: sc, 35 } 36 } 37 38 // Build builds an executor from a plan. 39 func (b *Builder) Build(plan planner.Plan) Executor { 40 switch p := plan.(type) { 41 case *planner.DDL: 42 return b.buildDDL(p) 43 case *planner.Simple: 44 return b.buildSimple(p) 45 case *planner.Insert: 46 return b.buildInsert(p) 47 case *planner.PhysicalMatch: 48 return b.buildMatch(p) 49 case *planner.PhysicalProjection: 50 return b.buildProjection(p) 51 case *planner.PhysicalSelection: 52 return b.buildSelection(p) 53 default: 54 b.err = errors.Errorf("unknown plan: %T", plan) 55 } 56 return nil 57 } 58 59 // Error returns the internal error encountered while building. 60 func (b *Builder) Error() error { 61 return b.err 62 } 63 64 func (b *Builder) buildDDL(plan *planner.DDL) Executor { 65 exec := &DDLExec{ 66 baseExecutor: newBaseExecutor(b.sc, plan.Columns(), plan.ID()), 67 statement: plan.Statement, 68 } 69 return exec 70 } 71 72 func (b *Builder) buildSimple(plan *planner.Simple) Executor { 73 var exec Executor 74 switch s := plan.Statement.(type) { 75 case *ast.ShowStmt: 76 exec = &ShowExec{ 77 baseExecutor: newBaseExecutor(b.sc, showStmtColumns[s.Tp], plan.ID()), 78 statement: s, 79 } 80 default: 81 exec = &SimpleExec{ 82 baseExecutor: newBaseExecutor(b.sc, plan.Columns(), plan.ID()), 83 statement: plan.Statement, 84 } 85 } 86 return exec 87 } 88 89 func (b *Builder) buildInsert(plan *planner.Insert) Executor { 90 exec := &InsertExec{ 91 baseExecutor: newBaseExecutor(b.sc, plan.Columns(), plan.ID()), 92 graph: plan.Graph, 93 insertions: plan.Insertions, 94 encoder: &codec.PropertyEncoder{}, 95 decoder: &codec.PropertyDecoder{}, 96 } 97 if plan.MatchPlan != nil { 98 exec.matchExec = b.Build(plan.MatchPlan) 99 } 100 return exec 101 } 102 103 func (b *Builder) buildMatch(plan *planner.PhysicalMatch) Executor { 104 exec := &MatchExec{ 105 baseExecutor: newBaseExecutor(b.sc, plan.Columns(), plan.ID()), 106 subgraph: plan.Subgraph, 107 } 108 return exec 109 } 110 111 func (b *Builder) buildProjection(plan *planner.PhysicalProjection) Executor { 112 childExec := b.Build(plan.Children()[0]) 113 exec := &ProjectionExec{ 114 baseExecutor: newBaseExecutor(b.sc, plan.Columns(), plan.ID(), childExec), 115 exprs: plan.Exprs, 116 } 117 return exec 118 } 119 120 func (b *Builder) buildSelection(plan *planner.PhysicalSelection) Executor { 121 childExec := b.Build(plan.Children()[0]) 122 exec := &SelectionExec{ 123 baseExecutor: newBaseExecutor(b.sc, plan.Columns(), plan.ID(), childExec), 124 condition: plan.Condition, 125 } 126 return exec 127 }