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 }