github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/subqueryalias.go (about) 1 // Copyright 2020-2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plan 16 17 import ( 18 "fmt" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 ) 22 23 // SubqueryAlias is a node that gives a subquery a name. 24 type SubqueryAlias struct { 25 UnaryNode 26 ColumnNames []string 27 name string 28 TextDefinition string 29 // OuterScopeVisibility is true when a SubqueryAlias (i.e. derived table) is contained in a subquery 30 // expression and is eligible to have visibility to outer scopes of the query. 31 OuterScopeVisibility bool 32 Correlated sql.ColSet 33 Volatile bool 34 CacheableCTESource bool 35 IsLateral bool 36 ScopeMapping map[sql.ColumnId]sql.Expression 37 id sql.TableId 38 cols sql.ColSet 39 } 40 41 var _ sql.Node = (*SubqueryAlias)(nil) 42 var _ sql.CollationCoercible = (*SubqueryAlias)(nil) 43 var _ sql.RenameableNode = (*SubqueryAlias)(nil) 44 45 // NewSubqueryAlias creates a new SubqueryAlias node. 46 func NewSubqueryAlias(name, textDefinition string, node sql.Node) *SubqueryAlias { 47 return &SubqueryAlias{ 48 UnaryNode: UnaryNode{Child: node}, 49 name: name, 50 TextDefinition: textDefinition, 51 OuterScopeVisibility: false, 52 } 53 } 54 55 // WithId implements sql.TableIdNode 56 func (sq *SubqueryAlias) WithId(id sql.TableId) TableIdNode { 57 ret := *sq 58 ret.id = id 59 return &ret 60 } 61 62 // Id implements sql.TableIdNode 63 func (sq *SubqueryAlias) Id() sql.TableId { 64 return sq.id 65 } 66 67 // WithColumns implements sql.TableIdNode 68 func (sq *SubqueryAlias) WithColumns(set sql.ColSet) TableIdNode { 69 ret := *sq 70 ret.cols = set 71 return &ret 72 } 73 74 // Columns implements sql.TableIdNode 75 func (sq *SubqueryAlias) Columns() sql.ColSet { 76 return sq.cols 77 } 78 79 // AsView returns the view wrapper for this subquery 80 func (sq *SubqueryAlias) AsView(createViewStmt string) *sql.View { 81 return sql.NewView(sq.Name(), sq, sq.TextDefinition, createViewStmt) 82 } 83 84 // Name implements the Table interface. 85 func (sq *SubqueryAlias) Name() string { return sq.name } 86 87 func (sq *SubqueryAlias) WithName(n string) sql.Node { 88 ret := *sq 89 ret.name = n 90 return &ret 91 } 92 93 func (sq *SubqueryAlias) IsReadOnly() bool { 94 return sq.Child.IsReadOnly() 95 } 96 97 // Schema implements the Node interface. 98 func (sq *SubqueryAlias) Schema() sql.Schema { 99 childSchema := sq.Child.Schema() 100 schema := make(sql.Schema, len(childSchema)) 101 for i, col := range childSchema { 102 c := *col 103 c.Source = sq.name 104 if len(sq.ColumnNames) > 0 { 105 c.Name = sq.ColumnNames[i] 106 } 107 schema[i] = &c 108 } 109 return schema 110 } 111 112 // WithChildren implements the Node interface. 113 func (sq *SubqueryAlias) WithChildren(children ...sql.Node) (sql.Node, error) { 114 if len(children) != 1 { 115 return nil, sql.ErrInvalidChildrenNumber.New(sq, len(children), 1) 116 } 117 118 nn := *sq 119 nn.Child = children[0] 120 return &nn, nil 121 } 122 123 // CheckPrivileges implements the interface sql.Node. 124 func (sq *SubqueryAlias) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 125 return sq.Child.CheckPrivileges(ctx, opChecker) 126 } 127 128 // CollationCoercibility implements the interface sql.CollationCoercible. 129 func (sq *SubqueryAlias) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 130 return sql.GetCoercibility(ctx, sq.Child) 131 } 132 133 func (sq *SubqueryAlias) WithChild(n sql.Node) *SubqueryAlias { 134 ret := *sq 135 ret.Child = n 136 return &ret 137 } 138 139 func (sq *SubqueryAlias) CanCacheResults() bool { 140 return sq.Correlated.Empty() && !sq.Volatile 141 } 142 143 func (sq *SubqueryAlias) WithCorrelated(cols sql.ColSet) *SubqueryAlias { 144 ret := *sq 145 ret.Correlated = cols 146 return &ret 147 } 148 149 func (sq *SubqueryAlias) WithVolatile(v bool) *SubqueryAlias { 150 ret := *sq 151 ret.Volatile = v 152 return &ret 153 } 154 155 func (sq *SubqueryAlias) WithScopeMapping(cols map[sql.ColumnId]sql.Expression) *SubqueryAlias { 156 ret := *sq 157 ret.ScopeMapping = cols 158 return &ret 159 } 160 161 // Opaque implements the OpaqueNode interface. 162 func (sq *SubqueryAlias) Opaque() bool { 163 return true 164 } 165 166 func (sq *SubqueryAlias) String() string { 167 pr := sql.NewTreePrinter() 168 _ = pr.WriteNode("SubqueryAlias") 169 children := make([]string, 5) 170 children[0] = fmt.Sprintf("name: %s", sq.name) 171 children[1] = fmt.Sprintf("outerVisibility: %t", sq.OuterScopeVisibility) 172 children[2] = fmt.Sprintf("isLateral: %t", sq.IsLateral) 173 children[3] = fmt.Sprintf("cacheable: %t", sq.CanCacheResults()) 174 children[4] = sq.Child.String() 175 _ = pr.WriteChildren(children...) 176 return pr.String() 177 } 178 179 func (sq *SubqueryAlias) DebugString() string { 180 pr := sql.NewTreePrinter() 181 _ = pr.WriteNode("SubqueryAlias") 182 children := make([]string, 7) 183 children[0] = fmt.Sprintf("name: %s", sq.name) 184 children[1] = fmt.Sprintf("outerVisibility: %t", sq.OuterScopeVisibility) 185 children[2] = fmt.Sprintf("isLateral: %t", sq.IsLateral) 186 children[3] = fmt.Sprintf("cacheable: %t", sq.CanCacheResults()) 187 children[4] = fmt.Sprintf("colSet: %s", sq.Columns()) 188 children[5] = fmt.Sprintf("tableId: %d", sq.Id()) 189 children[6] = sql.DebugString(sq.Child) 190 _ = pr.WriteChildren(children...) 191 return pr.String() 192 } 193 194 func (sq *SubqueryAlias) WithColumnNames(columns []string) *SubqueryAlias { 195 ret := *sq 196 ret.ColumnNames = columns 197 return &ret 198 }