vitess.io/vitess@v0.16.2/go/vt/vtgate/planbuilder/operators/subquery.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
    18  
    19  import (
    20  	"vitess.io/vitess/go/vt/sqlparser"
    21  	"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops"
    22  	"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
    23  )
    24  
    25  type (
    26  	// SubQuery stores the information about subquery
    27  	SubQuery struct {
    28  		Outer ops.Operator
    29  		Inner []*SubQueryInner
    30  
    31  		noColumns
    32  		noPredicates
    33  	}
    34  
    35  	// SubQueryInner stores the subquery information for a select statement
    36  	SubQueryInner struct {
    37  		// Inner is the Operator inside the parenthesis of the subquery.
    38  		// i.e: select (select 1 union select 1), the Inner here would be
    39  		// of type Concatenate since we have a Union.
    40  		Inner ops.Operator
    41  
    42  		// ExtractedSubquery contains all information we need about this subquery
    43  		ExtractedSubquery *sqlparser.ExtractedSubquery
    44  
    45  		noColumns
    46  		noPredicates
    47  	}
    48  )
    49  
    50  var _ ops.Operator = (*SubQuery)(nil)
    51  var _ ops.Operator = (*SubQueryInner)(nil)
    52  
    53  // Clone implements the Operator interface
    54  func (s *SubQueryInner) Clone(inputs []ops.Operator) ops.Operator {
    55  	return &SubQueryInner{
    56  		Inner:             inputs[0],
    57  		ExtractedSubquery: s.ExtractedSubquery,
    58  	}
    59  }
    60  
    61  // Inputs implements the Operator interface
    62  func (s *SubQueryInner) Inputs() []ops.Operator {
    63  	return []ops.Operator{s.Inner}
    64  }
    65  
    66  // Clone implements the Operator interface
    67  func (s *SubQuery) Clone(inputs []ops.Operator) ops.Operator {
    68  	result := &SubQuery{
    69  		Outer: inputs[0],
    70  	}
    71  	for idx := range s.Inner {
    72  		inner, ok := inputs[idx+1].(*SubQueryInner)
    73  		if !ok {
    74  			panic("got bad input")
    75  		}
    76  		result.Inner = append(result.Inner, inner)
    77  	}
    78  	return result
    79  }
    80  
    81  // Inputs implements the Operator interface
    82  func (s *SubQuery) Inputs() []ops.Operator {
    83  	operators := []ops.Operator{s.Outer}
    84  	for _, inner := range s.Inner {
    85  		operators = append(operators, inner)
    86  	}
    87  	return operators
    88  }
    89  
    90  func createSubqueryFromStatement(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) (*SubQuery, error) {
    91  	if len(ctx.SemTable.SubqueryMap[stmt]) == 0 {
    92  		return nil, nil
    93  	}
    94  	subq := &SubQuery{}
    95  	for _, sq := range ctx.SemTable.SubqueryMap[stmt] {
    96  		opInner, err := createLogicalOperatorFromAST(ctx, sq.Subquery.Select)
    97  		if err != nil {
    98  			return nil, err
    99  		}
   100  		if horizon, ok := opInner.(*Horizon); ok {
   101  			opInner = horizon.Source
   102  		}
   103  
   104  		subq.Inner = append(subq.Inner, &SubQueryInner{
   105  			ExtractedSubquery: sq,
   106  			Inner:             opInner,
   107  		})
   108  	}
   109  	return subq, nil
   110  }