Skip to content

Commit

Permalink
Add several features that unblock mysql workbench (#573)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinai Rachakonda authored Oct 4, 2021
1 parent db29369 commit 6baf28a
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 0 deletions.
16 changes: 16 additions & 0 deletions enginetest/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -5328,6 +5328,22 @@ var QueryTests = []QueryTest{
Query: `SELECT EXISTS (SELECT pk FROM one_pk WHERE pk > 4)`,
Expected: []sql.Row{{false}},
},
{
Query: `SHOW STATUS`,
Expected: []sql.Row{},
},
{
Query: `SHOW GLOBAL STATUS`,
Expected: []sql.Row{},
},
{
Query: `SHOW SESSION STATUS`,
Expected: []sql.Row{},
},
{
Query: `SHOW STATUS LIKE 'Bytes_received'`,
Expected: []sql.Row{},
},
}

var KeylessQueries = []QueryTest{
Expand Down
30 changes: 30 additions & 0 deletions enginetest/variable_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,36 @@ var VariableQueries = []ScriptTest{
{"charset", "charset", "charset"},
},
},
{
Name: "set character set",
SetUpScript: []string{
`set character set utf8`,
},
Query: "SELECT @@character_set_client, @@character_set_connection, @@character_set_results",
Expected: []sql.Row{
{"utf8", "utf8mb4", "utf8"},
},
},
{
Name: "set charset",
SetUpScript: []string{
`set charset utf8`,
},
Query: "SELECT @@character_set_client, @@character_set_connection, @@character_set_results",
Expected: []sql.Row{
{"utf8", "utf8mb4", "utf8"},
},
},
{
Name: "set charset quoted",
SetUpScript: []string{
`set charset 'utf8'`,
},
Query: "SELECT @@character_set_client, @@character_set_connection, @@character_set_results",
Expected: []sql.Row{
{"utf8", "utf8mb4", "utf8"},
},
},
{
Name: "set system variable to bareword",
SetUpScript: []string{
Expand Down
42 changes: 42 additions & 0 deletions sql/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,34 @@ func convertSet(ctx *sql.Context, n *sqlparser.Set) (sql.Node, error) {
})
}

// Special case: SET CHARACTER SET (CHARSET) expands to 3 different system variables. Although we do not support very
// many character sets, changing these variables should not have any effect currently as our character set support is
// mostly hardcoded to utf8mb4.
// See https://dev.mysql.com/doc/refman/5.7/en/set-character-set.html.
if isCharset(n.Exprs) {
csd, err := ctx.GetSessionVariable(ctx, "character_set_database")
if err != nil {
return nil, err
}

return convertSet(ctx, &sqlparser.Set{
Exprs: sqlparser.SetVarExprs{
&sqlparser.SetVarExpr{
Name: sqlparser.NewColName("character_set_client"),
Expr: n.Exprs[0].Expr,
},
&sqlparser.SetVarExpr{
Name: sqlparser.NewColName("character_set_results"),
Expr: n.Exprs[0].Expr,
},
&sqlparser.SetVarExpr{
Name: sqlparser.NewColName("character_set_connection"),
Expr: &sqlparser.SQLVal{Type: sqlparser.StrVal, Val: []byte(csd.(string))},
},
},
})
}

exprs, err := setExprsToExpressions(ctx, n.Exprs)
if err != nil {
return nil, err
Expand All @@ -362,6 +390,14 @@ func isSetNames(exprs sqlparser.SetVarExprs) bool {
return strings.ToLower(exprs[0].Name.String()) == "names"
}

func isCharset(exprs sqlparser.SetVarExprs) bool {
if len(exprs) != 1 {
return false
}

return strings.ToLower(exprs[0].Name.String()) == "charset"
}

func convertShow(ctx *sql.Context, s *sqlparser.Show, query string) (sql.Node, error) {
showType := strings.ToLower(s.Type)
switch showType {
Expand Down Expand Up @@ -572,6 +608,12 @@ func convertShow(ctx *sql.Context, s *sqlparser.Show, query string) (sql.Node, e
}

return infoSchemaSelect, nil
case sqlparser.KeywordString(sqlparser.STATUS):
if s.Scope == sqlparser.GlobalStr {
return plan.NewShowStatus(plan.ShowStatusModifier_Global), nil
}

return plan.NewShowStatus(plan.ShowStatusModifier_Session), nil
default:
unsupportedShow := fmt.Sprintf("SHOW %s", s.Type)
return nil, ErrUnsupportedFeature.New(unsupportedShow)
Expand Down
75 changes: 75 additions & 0 deletions sql/plan/show_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2021 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package plan

import (
"github.com/dolthub/vitess/go/sqltypes"

"github.com/dolthub/go-mysql-server/sql"
)

// ShowStatus implements the SHOW STATUS MySQL command.
// TODO: This is just a stub implementation that returns an empty set. The actual functionality needs to be implemented
// in the future.
type ShowStatus struct {
modifier ShowStatusModifier
}

var _ sql.Node = (*ShowStatus)(nil)

type ShowStatusModifier byte

const (
ShowStatusModifier_Session ShowStatusModifier = iota
ShowStatusModifier_Global
)

// NewShowStatus returns a new ShowStatus reference.
func NewShowStatus(modifier ShowStatusModifier) *ShowStatus {
return &ShowStatus{modifier: modifier}
}

// Resolved implements sql.Node interface.
func (s *ShowStatus) Resolved() bool {
return true
}

// String implements sql.Node interface.
func (s *ShowStatus) String() string {
return "SHOW STATUS"
}

// Schema implements sql.Node interface.
func (s *ShowStatus) Schema() sql.Schema {
return sql.Schema{
{Name: "Variable_name", Type: sql.MustCreateStringWithDefaults(sqltypes.VarChar, 64), Default: nil, Nullable: false},
{Name: "Value", Type: sql.MustCreateStringWithDefaults(sqltypes.VarChar, 2048), Default: nil, Nullable: false},
}
}

// Children implements sql.Node interface.
func (s *ShowStatus) Children() []sql.Node {
return nil
}

// RowIter implements sql.Node interface.
func (s *ShowStatus) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) {
return sql.RowsToRowIter(), nil
}

// WithChildren implements sql.Node interface.
func (s *ShowStatus) WithChildren(node ...sql.Node) (sql.Node, error) {
return NewShowStatus(s.modifier), nil
}

0 comments on commit 6baf28a

Please sign in to comment.