github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/virtual_column_table.go (about) 1 // Copyright 2023 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 "strings" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 ) 23 24 // VirtualColumnTable is a sql.TableNode that combines a ResolvedTable with a Project, the latter of which is used 25 // to add the values of virtual columns to the table. 26 type VirtualColumnTable struct { 27 sql.Table 28 Projections []sql.Expression 29 } 30 31 var _ sql.TableWrapper = (*VirtualColumnTable)(nil) 32 var _ sql.MutableTableWrapper = (*VirtualColumnTable)(nil) 33 var _ sql.IndexedTable = (*VirtualColumnTable)(nil) 34 35 func (v *VirtualColumnTable) Underlying() sql.Table { 36 return v.Table 37 } 38 39 func (v VirtualColumnTable) WithUnderlying(table sql.Table) sql.Table { 40 v.Table = table 41 return &v 42 } 43 44 // NewVirtualColumnTable creates a new VirtualColumnTable. 45 func NewVirtualColumnTable(table sql.Table, projections []sql.Expression) *VirtualColumnTable { 46 return &VirtualColumnTable{ 47 Table: table, 48 Projections: projections, 49 } 50 } 51 52 func (v *VirtualColumnTable) LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) { 53 // this will panic if we fail to correctly unwrap the underlying table during analysis to determine if it supports 54 // index lookups 55 return v.Table.(sql.IndexedTable).LookupPartitions(context, lookup) 56 } 57 58 func (v *VirtualColumnTable) String() string { 59 pr := sql.NewTreePrinter() 60 _ = pr.WriteNode("VirtualColumnTable") 61 children := make([]string, 2) 62 children[0] = fmt.Sprintf("name: %s", v.Name()) 63 exprs := make([]string, len(v.Projections)) 64 for i, expr := range v.Projections { 65 exprs[i] = expr.String() 66 } 67 children[1] = fmt.Sprintf("columns: [%s]", strings.Join(exprs, ", ")) 68 _ = pr.WriteChildren(children...) 69 70 return pr.String() 71 } 72 73 func (v *VirtualColumnTable) DebugString() string { 74 pr := sql.NewTreePrinter() 75 _ = pr.WriteNode("VirtualColumnTable") 76 children := make([]string, 3) 77 children[0] = fmt.Sprintf("name: %s", v.Name()) 78 exprs := make([]string, len(v.Projections)) 79 for i, expr := range v.Projections { 80 exprs[i] = sql.DebugString(expr) 81 } 82 83 children[1] = fmt.Sprintf("columns: [%s]", strings.Join(exprs, ", ")) 84 children[2] = TableDebugString(v.Table) 85 _ = pr.WriteChildren(children...) 86 87 return pr.String() 88 } 89 90 // FindVirtualColumnTable returns the plan.VirtualTableColumn being wrapped by the given table, if any. 91 func FindVirtualColumnTable(table sql.Table) (*VirtualColumnTable, bool) { 92 if vct, ok := table.(*VirtualColumnTable); ok { 93 return vct, true 94 } 95 if tw, ok := table.(sql.TableWrapper); ok { 96 return FindVirtualColumnTable(tw.Underlying()) 97 } 98 return nil, false 99 }