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  }