vitess.io/vitess@v0.16.2/go/vt/vtgate/planbuilder/filter.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 planbuilder
    18  
    19  import (
    20  	"vitess.io/vitess/go/mysql/collations"
    21  	"vitess.io/vitess/go/vt/sqlparser"
    22  	"vitess.io/vitess/go/vt/vterrors"
    23  	"vitess.io/vitess/go/vt/vtgate/engine"
    24  	"vitess.io/vitess/go/vt/vtgate/evalengine"
    25  	"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
    26  )
    27  
    28  type (
    29  	// filter is the logicalPlan for engine.Filter.
    30  	filter struct {
    31  		logicalPlanCommon
    32  		efilter *engine.Filter
    33  	}
    34  
    35  	simpleConverterLookup struct {
    36  		ctx               *plancontext.PlanningContext
    37  		plan              logicalPlan
    38  		canPushProjection bool
    39  	}
    40  )
    41  
    42  var _ logicalPlan = (*filter)(nil)
    43  var _ evalengine.TranslationLookup = (*simpleConverterLookup)(nil)
    44  
    45  func (s *simpleConverterLookup) ColumnLookup(col *sqlparser.ColName) (int, error) {
    46  	offset, added, err := pushProjection(s.ctx, &sqlparser.AliasedExpr{Expr: col}, s.plan, true, true, false)
    47  	if err != nil {
    48  		return 0, err
    49  	}
    50  	if added && !s.canPushProjection {
    51  		return 0, vterrors.VT13001("column should not be pushed to projection while doing a column lookup")
    52  	}
    53  	return offset, nil
    54  }
    55  
    56  func (s *simpleConverterLookup) CollationForExpr(expr sqlparser.Expr) collations.ID {
    57  	return s.ctx.SemTable.CollationForExpr(expr)
    58  }
    59  
    60  func (s *simpleConverterLookup) DefaultCollation() collations.ID {
    61  	return s.ctx.SemTable.Collation
    62  }
    63  
    64  // newFilter builds a new filter.
    65  func newFilter(ctx *plancontext.PlanningContext, plan logicalPlan, expr sqlparser.Expr) (*filter, error) {
    66  	scl := &simpleConverterLookup{
    67  		ctx:  ctx,
    68  		plan: plan,
    69  	}
    70  	predicate, err := evalengine.Translate(expr, scl)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	return &filter{
    75  		logicalPlanCommon: newBuilderCommon(plan),
    76  		efilter: &engine.Filter{
    77  			Predicate:    predicate,
    78  			ASTPredicate: expr,
    79  		},
    80  	}, nil
    81  }
    82  
    83  // Primitive implements the logicalPlan interface
    84  func (l *filter) Primitive() engine.Primitive {
    85  	l.efilter.Input = l.input.Primitive()
    86  	return l.efilter
    87  }