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  }