github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/showcolumns.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 "github.com/dolthub/vitess/go/sqltypes" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 "github.com/dolthub/go-mysql-server/sql/transform" 22 "github.com/dolthub/go-mysql-server/sql/types" 23 ) 24 25 // ShowColumns shows the columns details of a table. 26 type ShowColumns struct { 27 UnaryNode 28 Full bool 29 Indexes []sql.Index 30 targetSchema sql.Schema 31 } 32 33 var VarChar25000 = types.MustCreateStringWithDefaults(sqltypes.VarChar, 25_000) 34 var ( 35 showColumnsSchema = sql.Schema{ 36 {Name: "Field", Type: VarChar25000}, 37 {Name: "Type", Type: VarChar25000}, 38 {Name: "Null", Type: VarChar25000}, 39 {Name: "Key", Type: VarChar25000}, 40 {Name: "Default", Type: VarChar25000, Nullable: true}, 41 {Name: "Extra", Type: VarChar25000}, 42 } 43 44 showColumnsFullSchema = sql.Schema{ 45 {Name: "Field", Type: VarChar25000}, 46 {Name: "Type", Type: VarChar25000}, 47 {Name: "Collation", Type: VarChar25000, Nullable: true}, 48 {Name: "Null", Type: VarChar25000}, 49 {Name: "Key", Type: VarChar25000}, 50 {Name: "Default", Type: VarChar25000, Nullable: true}, 51 {Name: "Extra", Type: VarChar25000}, 52 {Name: "Privileges", Type: VarChar25000}, 53 {Name: "Comment", Type: VarChar25000}, 54 } 55 ) 56 57 // NewShowColumns creates a new ShowColumns node. 58 func NewShowColumns(full bool, child sql.Node) *ShowColumns { 59 return &ShowColumns{UnaryNode: UnaryNode{Child: child}, Full: full} 60 } 61 62 var _ sql.Node = (*ShowColumns)(nil) 63 var _ sql.Expressioner = (*ShowColumns)(nil) 64 var _ sql.SchemaTarget = (*ShowColumns)(nil) 65 var _ sql.CollationCoercible = (*ShowColumns)(nil) 66 67 // Schema implements the sql.Node interface. 68 func (s *ShowColumns) Schema() sql.Schema { 69 if s.Full { 70 return showColumnsFullSchema 71 } 72 return showColumnsSchema 73 } 74 75 // Resolved implements the sql.Node interface. 76 func (s *ShowColumns) Resolved() bool { 77 return s.Child.Resolved() && s.targetSchema.Resolved() 78 } 79 80 func (s *ShowColumns) IsReadOnly() bool { 81 return true 82 } 83 84 func (s *ShowColumns) Expressions() []sql.Expression { 85 if len(s.targetSchema) == 0 { 86 return nil 87 } 88 89 return transform.WrappedColumnDefaults(s.targetSchema) 90 } 91 92 func (s ShowColumns) WithExpressions(exprs ...sql.Expression) (sql.Node, error) { 93 if len(exprs) != len(s.targetSchema) { 94 return nil, sql.ErrInvalidChildrenNumber.New(s, len(exprs), len(s.targetSchema)) 95 } 96 97 sch, err := transform.SchemaWithDefaults(s.targetSchema, exprs) 98 if err != nil { 99 return nil, err 100 } 101 102 s.targetSchema = sch 103 return &s, nil 104 } 105 106 func (s *ShowColumns) WithTargetSchema(schema sql.Schema) (sql.Node, error) { 107 ss := *s 108 ss.targetSchema = schema 109 return &ss, nil 110 } 111 112 func (s *ShowColumns) TargetSchema() sql.Schema { 113 return s.targetSchema 114 } 115 116 // WithChildren implements the Node interface. 117 func (s *ShowColumns) WithChildren(children ...sql.Node) (sql.Node, error) { 118 if len(children) != 1 { 119 return nil, sql.ErrInvalidChildrenNumber.New(s, len(children), 1) 120 } 121 122 ss := *s 123 ss.Child = children[0] 124 return &ss, nil 125 } 126 127 // CheckPrivileges implements the interface sql.Node. 128 func (s *ShowColumns) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 129 // The table won't be visible during the resolution step if the user doesn't have the correct privileges 130 return true 131 } 132 133 // CollationCoercibility implements the interface sql.CollationCoercible. 134 func (*ShowColumns) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 135 return sql.Collation_binary, 7 136 } 137 138 func (s *ShowColumns) String() string { 139 tp := sql.NewTreePrinter() 140 if s.Full { 141 _ = tp.WriteNode("ShowColumns(full)") 142 } else { 143 _ = tp.WriteNode("ShowColumns") 144 } 145 _ = tp.WriteChildren(s.Child.String()) 146 return tp.String() 147 } 148 149 func (s *ShowColumns) DebugString() string { 150 tp := sql.NewTreePrinter() 151 if s.Full { 152 _ = tp.WriteNode("ShowColumns(full)") 153 } else { 154 _ = tp.WriteNode("ShowColumns") 155 } 156 157 var children []string 158 for _, col := range s.targetSchema { 159 children = append(children, sql.DebugString(col)) 160 } 161 162 children = append(children, sql.DebugString(s.Child)) 163 164 _ = tp.WriteChildren(children...) 165 return tp.String() 166 } 167 168 // GetColumnFromIndexExpr returns column from the table given using the expression string given, in the form 169 // "table.column". Returns nil if the expression doesn't represent a column. 170 func GetColumnFromIndexExpr(expr string, table sql.Table) *sql.Column { 171 for _, col := range table.Schema() { 172 if col.Source+"."+col.Name == expr { 173 return col 174 } 175 } 176 177 return nil 178 }