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

     1  /*
     2  Copyright 2019 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/sqltypes"
    21  	"vitess.io/vitess/go/vt/sqlparser"
    22  	"vitess.io/vitess/go/vt/vtgate/engine"
    23  	"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
    24  )
    25  
    26  var _ logicalPlan = (*mergeSort)(nil)
    27  
    28  // mergeSort is a pseudo-primitive. It amends the
    29  // the underlying Route to perform a merge sort.
    30  // It's differentiated as a separate primitive
    31  // because some operations cannot be pushed down,
    32  // which would otherwise be possible with a simple route.
    33  // Since ORDER BY happens near the end of the SQL processing,
    34  // most functions of this primitive are unreachable.
    35  type mergeSort struct {
    36  	resultsBuilder
    37  	truncateColumnCount int
    38  }
    39  
    40  // newMergeSort builds a new mergeSort.
    41  func newMergeSort(rb *route) *mergeSort {
    42  	ms := &mergeSort{
    43  		resultsBuilder: newResultsBuilder(rb, nil),
    44  	}
    45  	ms.truncater = ms
    46  	return ms
    47  }
    48  
    49  // SetTruncateColumnCount satisfies the truncater interface.
    50  // This function records the truncate column count and sets
    51  // it later on the eroute during wire-up phase.
    52  func (ms *mergeSort) SetTruncateColumnCount(count int) {
    53  	ms.truncateColumnCount = count
    54  }
    55  
    56  // Primitive implements the logicalPlan interface
    57  func (ms *mergeSort) Primitive() engine.Primitive {
    58  	return ms.input.Primitive()
    59  }
    60  
    61  // Wireup implements the logicalPlan interface
    62  func (ms *mergeSort) Wireup(plan logicalPlan, jt *jointab) error {
    63  	// If the route has to do the ordering, and if any columns are Text,
    64  	// we have to request the corresponding weight_string from mysql
    65  	// and use that value instead. This is because we cannot mimic
    66  	// mysql's collation behavior yet.
    67  	rb := ms.input.(*route)
    68  	for i, orderby := range rb.eroute.OrderBy {
    69  		rc := ms.resultColumns[orderby.Col]
    70  		// Add a weight_string column if we know that the column is a textual column or if its type is unknown
    71  		if sqltypes.IsText(rc.column.typ) || rc.column.typ == sqltypes.Null {
    72  			var err error
    73  			rb.eroute.OrderBy[i].WeightStringCol, err = rb.SupplyWeightString(orderby.Col, orderby.FromGroupBy)
    74  			if err != nil {
    75  				_, isUnsupportedErr := err.(UnsupportedSupplyWeightString)
    76  				if isUnsupportedErr {
    77  					continue
    78  				}
    79  				return err
    80  			}
    81  			ms.truncateColumnCount = len(ms.resultColumns)
    82  		}
    83  	}
    84  	rb.eroute.TruncateColumnCount = ms.truncateColumnCount
    85  	return ms.input.Wireup(plan, jt)
    86  }
    87  
    88  func (ms *mergeSort) WireupGen4(ctx *plancontext.PlanningContext) error {
    89  	return ms.input.WireupGen4(ctx)
    90  }
    91  
    92  // OutputColumns implements the logicalPlan interface
    93  func (ms *mergeSort) OutputColumns() []sqlparser.SelectExpr {
    94  	outputCols := ms.input.OutputColumns()
    95  	if ms.truncateColumnCount > 0 {
    96  		return outputCols[:ms.truncateColumnCount]
    97  	}
    98  	return outputCols
    99  }