github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/show_charset.go (about)

     1  // Copyright 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/types"
    21  
    22  	"github.com/dolthub/go-mysql-server/sql"
    23  )
    24  
    25  type ShowCharset struct {
    26  	CharacterSetTable sql.Node
    27  }
    28  
    29  var _ sql.Node = (*ShowCharset)(nil)
    30  var _ sql.CollationCoercible = (*ShowCharset)(nil)
    31  
    32  // NewShowCharset returns a new ShowCharset reference.
    33  func NewShowCharset() *ShowCharset {
    34  	return &ShowCharset{}
    35  }
    36  
    37  // Resolved implements sql.Node interface. The function always returns true.
    38  func (sc *ShowCharset) Resolved() bool {
    39  	return true
    40  }
    41  
    42  // WithChildren implements the Node interface.
    43  func (sc *ShowCharset) WithChildren(children ...sql.Node) (sql.Node, error) {
    44  	expected := len(sc.Children())
    45  	if len(children) != expected {
    46  		return nil, sql.ErrInvalidChildrenNumber.New(sc, len(children), expected)
    47  	}
    48  
    49  	return sc, nil
    50  }
    51  
    52  // CheckPrivileges implements the interface sql.Node.
    53  func (sc *ShowCharset) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool {
    54  	return true
    55  }
    56  
    57  func (sc *ShowCharset) IsReadOnly() bool {
    58  	return true
    59  }
    60  
    61  // CollationCoercibility implements the interface sql.CollationCoercible.
    62  func (*ShowCharset) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
    63  	return sql.Collation_binary, 7
    64  }
    65  
    66  func (sc *ShowCharset) String() string {
    67  	return "SHOW CHARSET"
    68  }
    69  
    70  // Note how this Schema differs in order from the information_schema.character_sets table.
    71  func (sc *ShowCharset) Schema() sql.Schema {
    72  	return sql.Schema{
    73  		{Name: "Charset", Type: types.MustCreateStringWithDefaults(sqltypes.VarChar, 64), Default: nil, Nullable: false},
    74  		{Name: "Description", Type: types.MustCreateStringWithDefaults(sqltypes.VarChar, 2048), Default: nil, Nullable: false},
    75  		{Name: "Default collation", Type: types.MustCreateStringWithDefaults(sqltypes.VarChar, 64), Default: nil, Nullable: false},
    76  		{Name: "Maxlen", Type: types.Uint64, Default: nil, Nullable: false},
    77  	}
    78  }
    79  
    80  func (sc *ShowCharset) Children() []sql.Node {
    81  	if sc.CharacterSetTable == nil {
    82  		return nil
    83  	}
    84  	return []sql.Node{sc.CharacterSetTable}
    85  }
    86  
    87  func (sc *ShowCharset) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) {
    88  	//TODO: use the information_schema table instead, currently bypassing it to show currently-implemented charsets
    89  	//ri, err := sc.CharacterSetTable.RowIter(ctx, row)
    90  	//if err != nil {
    91  	//	return nil, err
    92  	//}
    93  	//return &showCharsetIter{originalIter: ri}, nil
    94  
    95  	var rows []sql.Row
    96  	iter := sql.NewCharacterSetsIterator()
    97  	for charset, ok := iter.Next(); ok; charset, ok = iter.Next() {
    98  		if charset.Encoder != nil && charset.BinaryCollation.Sorter() != nil && charset.DefaultCollation.Sorter() != nil {
    99  			rows = append(rows, sql.Row{
   100  				charset.Name,
   101  				charset.Description,
   102  				charset.DefaultCollation.String(),
   103  				uint64(charset.MaxLength),
   104  			})
   105  		}
   106  	}
   107  	return sql.RowsToRowIter(rows...), nil
   108  }
   109  
   110  type showCharsetIter struct {
   111  	originalIter sql.RowIter
   112  }
   113  
   114  func (sci *showCharsetIter) Next(ctx *sql.Context) (sql.Row, error) {
   115  	row, err := sci.originalIter.Next(ctx)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	// switch the ordering (see notes on Schema())
   121  	defaultCollationName := row[1]
   122  
   123  	row[1] = row[2]
   124  	row[2] = defaultCollationName
   125  
   126  	return row, nil
   127  }
   128  
   129  func (sci *showCharsetIter) Close(ctx *sql.Context) error {
   130  	return sci.originalIter.Close(ctx)
   131  }