vitess.io/vitess@v0.16.2/go/vt/vtgate/planbuilder/operators/operator.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Package operators contains the operators used to plan queries.
    18  /*
    19  The operators go through a few phases while planning:
    20  1. Logical
    21     In this first pass, we build an operator tree from the incoming parsed query.
    22     It will contain logical joins - we still haven't decided on the join algorithm to use yet.
    23     At the leaves, it will contain QueryGraphs - these are the tables in the FROM clause
    24     that we can easily do join ordering on. The logical tree will represent the full query,
    25     including projections, grouping, ordering and so on.
    26  2. Physical
    27     Once the logical plan has been fully built, we go bottom up and plan which routes that will be used.
    28     During this phase, we will also decide which join algorithms should be used on the vtgate level
    29  3. Columns & Aggregation
    30     Once we know which queries will be sent to the tablets, we go over the tree and decide which
    31     columns each operator should output. At this point, we also do offset lookups,
    32     so we know at runtime from which columns in the input table we need to read.
    33  */
    34  package operators
    35  
    36  import (
    37  	"vitess.io/vitess/go/vt/sqlparser"
    38  	"vitess.io/vitess/go/vt/vterrors"
    39  	"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops"
    40  	"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
    41  )
    42  
    43  type (
    44  	// helper type that implements Inputs() returning nil
    45  	noInputs struct{}
    46  
    47  	// helper type that implements AddColumn() returning an error
    48  	noColumns struct{}
    49  
    50  	// helper type that implements AddPredicate() returning an error
    51  	noPredicates struct{}
    52  )
    53  
    54  func PlanQuery(ctx *plancontext.PlanningContext, selStmt sqlparser.Statement) (ops.Operator, error) {
    55  	op, err := createLogicalOperatorFromAST(ctx, selStmt)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	if err = CheckValid(op); err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	op, err = transformToPhysical(ctx, op)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	backup := Clone(op)
    70  
    71  	op, err = planHorizons(op)
    72  	if err == errNotHorizonPlanned {
    73  		op = backup
    74  	} else if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	if op, err = Compact(ctx, op); err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	return op, err
    83  }
    84  
    85  // Inputs implements the Operator interface
    86  func (noInputs) Inputs() []ops.Operator {
    87  	return nil
    88  }
    89  
    90  // AddColumn implements the Operator interface
    91  func (noColumns) AddColumn(*plancontext.PlanningContext, sqlparser.Expr) (int, error) {
    92  	return 0, vterrors.VT13001("the noColumns operator cannot accept columns")
    93  }
    94  
    95  // AddPredicate implements the Operator interface
    96  func (noPredicates) AddPredicate(*plancontext.PlanningContext, sqlparser.Expr) (ops.Operator, error) {
    97  	return nil, vterrors.VT13001("the noColumns operator cannot accept predicates")
    98  }