vitess.io/vitess@v0.16.2/go/vt/vtgate/semantics/real_table.go (about) 1 /* 2 Copyright 2020 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 semantics 18 19 import ( 20 "strings" 21 22 "vitess.io/vitess/go/mysql/collations" 23 "vitess.io/vitess/go/sqltypes" 24 vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" 25 "vitess.io/vitess/go/vt/sqlparser" 26 "vitess.io/vitess/go/vt/vterrors" 27 "vitess.io/vitess/go/vt/vtgate/vindexes" 28 ) 29 30 // RealTable contains the alias table expr and vindex table 31 type RealTable struct { 32 dbName, tableName string 33 ASTNode *sqlparser.AliasedTableExpr 34 Table *vindexes.Table 35 isInfSchema bool 36 } 37 38 var _ TableInfo = (*RealTable)(nil) 39 40 // dependencies implements the TableInfo interface 41 func (r *RealTable) dependencies(colName string, org originable) (dependencies, error) { 42 ts := org.tableSetFor(r.ASTNode) 43 for _, info := range r.getColumns() { 44 if strings.EqualFold(info.Name, colName) { 45 return createCertain(ts, ts, &info.Type), nil 46 } 47 } 48 49 if r.authoritative() { 50 return ¬hing{}, nil 51 } 52 return createUncertain(ts, ts), nil 53 } 54 55 // GetTables implements the TableInfo interface 56 func (r *RealTable) getTableSet(org originable) TableSet { 57 return org.tableSetFor(r.ASTNode) 58 } 59 60 // GetExprFor implements the TableInfo interface 61 func (r *RealTable) getExprFor(s string) (sqlparser.Expr, error) { 62 return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Unknown column '%s' in 'field list'", s) 63 } 64 65 // IsInfSchema implements the TableInfo interface 66 func (r *RealTable) IsInfSchema() bool { 67 return r.isInfSchema 68 } 69 70 // GetColumns implements the TableInfo interface 71 func (r *RealTable) getColumns() []ColumnInfo { 72 return vindexTableToColumnInfo(r.Table) 73 } 74 75 // GetExpr implements the TableInfo interface 76 func (r *RealTable) getExpr() *sqlparser.AliasedTableExpr { 77 return r.ASTNode 78 } 79 80 // GetVindexTable implements the TableInfo interface 81 func (r *RealTable) GetVindexTable() *vindexes.Table { 82 return r.Table 83 } 84 85 // Name implements the TableInfo interface 86 func (r *RealTable) Name() (sqlparser.TableName, error) { 87 return r.ASTNode.TableName() 88 } 89 90 // Authoritative implements the TableInfo interface 91 func (r *RealTable) authoritative() bool { 92 return r.Table != nil && r.Table.ColumnListAuthoritative 93 } 94 95 // Matches implements the TableInfo interface 96 func (r *RealTable) matches(name sqlparser.TableName) bool { 97 return (name.Qualifier.IsEmpty() || name.Qualifier.String() == r.dbName) && r.tableName == name.Name.String() 98 } 99 100 func vindexTableToColumnInfo(tbl *vindexes.Table) []ColumnInfo { 101 if tbl == nil { 102 return nil 103 } 104 nameMap := map[string]any{} 105 cols := make([]ColumnInfo, 0, len(tbl.Columns)) 106 for _, col := range tbl.Columns { 107 var collation collations.ID 108 if sqltypes.IsText(col.Type) { 109 collation, _ = collations.Local().LookupID(col.CollationName) 110 } 111 cols = append(cols, ColumnInfo{ 112 Name: col.Name.String(), 113 Type: Type{ 114 Type: col.Type, 115 Collation: collation, 116 }, 117 }) 118 nameMap[col.Name.String()] = nil 119 } 120 // If table is authoritative, we do not need ColumnVindexes to help in resolving the unqualified columns. 121 if tbl.ColumnListAuthoritative { 122 return cols 123 } 124 for _, vindex := range tbl.ColumnVindexes { 125 for _, column := range vindex.Columns { 126 name := column.String() 127 if _, exists := nameMap[name]; exists { 128 continue 129 } 130 cols = append(cols, ColumnInfo{ 131 Name: name, 132 }) 133 nameMap[name] = nil 134 } 135 } 136 return cols 137 }