Skip to content

Commit

Permalink
Merge pull request #7540 from GuptaManan100/show-meta-database-name
Browse files Browse the repository at this point in the history
Fix Metadata in SHOW queries
  • Loading branch information
systay committed Feb 26, 2021
2 parents 89766bd + 249e6a8 commit 5dee786
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 39 deletions.
12 changes: 12 additions & 0 deletions go/test/endtoend/vtgate/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ func TestShowColumns(t *testing.T) {
assertMatches(t, conn, "SHOW columns FROM `t5_null_vindex` in `ks`", expected)
}

func TestShowTables(t *testing.T) {
conn, err := mysql.Connect(context.Background(), &vtParams)
require.NoError(t, err)
defer conn.Close()

query := "show tables;"
qr := exec(t, conn, query)

assert.Equal(t, "information_schema", qr.Fields[0].Database)
assert.Equal(t, "Tables_in_ks", qr.Fields[0].Name)
}

func TestCastConvert(t *testing.T) {
conn, err := mysql.Connect(context.Background(), &vtParams)
require.NoError(t, err)
Expand Down
25 changes: 25 additions & 0 deletions go/vt/vtgate/engine/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

118 changes: 118 additions & 0 deletions go/vt/vtgate/engine/rename_fields.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
Copyright 2021 The Vitess Authors.
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 engine

import (
"vitess.io/vitess/go/sqltypes"
querypb "vitess.io/vitess/go/vt/proto/query"
"vitess.io/vitess/go/vt/proto/vtrpc"
"vitess.io/vitess/go/vt/vterrors"
)

var _ Primitive = (*RenameFields)(nil)

// RenameFields is a primitive that renames the fields
type RenameFields struct {
Cols []string
Indices []int
Input Primitive
noTxNeeded
}

// NewRenameField creates a new rename field
func NewRenameField(cols []string, indices []int, input Primitive) (*RenameFields, error) {
if len(cols) != len(indices) {
return nil, vterrors.New(vtrpc.Code_INTERNAL, "Unequal length of columns and indices in RenameField primitive")
}
return &RenameFields{
Cols: cols,
Indices: indices,
Input: input,
}, nil
}

// RouteType implements the primitive interface
func (r *RenameFields) RouteType() string {
return r.Input.RouteType()
}

// GetKeyspaceName implements the primitive interface
func (r *RenameFields) GetKeyspaceName() string {
return r.Input.GetKeyspaceName()
}

// GetTableName implements the primitive interface
func (r *RenameFields) GetTableName() string {
return r.Input.GetTableName()
}

// Execute implements the primitive interface
func (r *RenameFields) Execute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) {
qr, err := r.Input.Execute(vcursor, bindVars, wantfields)
if err != nil {
return nil, err
}
if wantfields {
r.renameFields(qr)
}
return qr, nil
}

func (r *RenameFields) renameFields(qr *sqltypes.Result) {
for ind, index := range r.Indices {
colName := r.Cols[ind]
qr.Fields[index].Name = colName
}
}

// StreamExecute implements the primitive interface
func (r *RenameFields) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error {
if wantfields {
innerCallback := callback
callback = func(result *sqltypes.Result) error {
r.renameFields(result)
return innerCallback(result)
}
}
return r.Input.StreamExecute(vcursor, bindVars, wantfields, callback)
}

// GetFields implements the primitive interface
func (r *RenameFields) GetFields(vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) {
qr, err := r.Input.GetFields(vcursor, bindVars)
if err != nil {
return nil, err
}
r.renameFields(qr)
return qr, nil
}

// Inputs implements the primitive interface
func (r *RenameFields) Inputs() []Primitive {
return []Primitive{r.Input}
}

// description implements the primitive interface
func (r *RenameFields) description() PrimitiveDescription {
return PrimitiveDescription{
OperatorType: "RenameFields",
Other: map[string]interface{}{
"Indices": r.Indices,
"Columns": r.Cols,
},
}
}
23 changes: 18 additions & 5 deletions go/vt/vtgate/planbuilder/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,32 +174,45 @@ func buildDBPlan(show *sqlparser.ShowBasic, vschema ContextVSchema) (engine.Prim

func buildPlanWithDB(show *sqlparser.ShowBasic, vschema ContextVSchema) (engine.Primitive, error) {
dbName := show.DbName
if sqlparser.SystemSchema(dbName) {
dbDestination := show.DbName
if sqlparser.SystemSchema(dbDestination) {
ks, err := vschema.AnyKeyspace()
if err != nil {
return nil, err
}
dbName = ks.Name
dbDestination = ks.Name
} else {
// Remove Database Name from the query.
show.DbName = ""
}
destination, keyspace, _, err := vschema.TargetDestination(dbName)
destination, keyspace, _, err := vschema.TargetDestination(dbDestination)
if err != nil {
return nil, err
}
if destination == nil {
destination = key.DestinationAnyShard{}
}

if dbName == "" {
dbName = keyspace.Name
}

query := sqlparser.String(show)
return &engine.Send{
var plan engine.Primitive
plan = &engine.Send{
Keyspace: keyspace,
TargetDestination: destination,
Query: query,
IsDML: false,
SingleShardOnly: true,
}, nil
}
if show.Command == sqlparser.Table {
plan, err = engine.NewRenameField([]string{"Tables_in_" + dbName}, []int{0}, plan)
if err != nil {
return nil, err
}
}
return plan, nil

}

Expand Down
88 changes: 60 additions & 28 deletions go/vt/vtgate/planbuilder/testdata/show_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -424,15 +424,26 @@
"QueryType": "SHOW",
"Original": "show tables",
"Instructions": {
"OperatorType": "Send",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"TargetDestination": "AnyShard()",
"IsDML": false,
"Query": "show tables",
"SingleShardOnly": true
"OperatorType": "RenameFields",
"Columns": [
"Tables_in_main"
],
"Indices": [
0
],
"Inputs": [
{
"OperatorType": "Send",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"TargetDestination": "AnyShard()",
"IsDML": false,
"Query": "show tables",
"SingleShardOnly": true
}
]
}
}

Expand All @@ -442,15 +453,26 @@
"QueryType": "SHOW",
"Original": "show tables from user",
"Instructions": {
"OperatorType": "Send",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"TargetDestination": "AnyShard()",
"IsDML": false,
"Query": "show tables",
"SingleShardOnly": true
"OperatorType": "RenameFields",
"Columns": [
"Tables_in_user"
],
"Indices": [
0
],
"Inputs": [
{
"OperatorType": "Send",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"TargetDestination": "AnyShard()",
"IsDML": false,
"Query": "show tables",
"SingleShardOnly": true
}
]
}
}

Expand All @@ -460,15 +482,25 @@
"QueryType": "SHOW",
"Original": "show tables from performance_schema",
"Instructions": {
"OperatorType": "Send",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"TargetDestination": "AnyShard()",
"IsDML": false,
"Query": "show tables from performance_schema",
"SingleShardOnly": true
"OperatorType": "RenameFields",
"Columns": [
"Tables_in_performance_schema"
],
"Indices": [
0
],
"Inputs": [
{
"OperatorType": "Send",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"TargetDestination": "AnyShard()",
"IsDML": false,
"Query": "show tables from performance_schema",
"SingleShardOnly": true
}
]
}
}

6 changes: 3 additions & 3 deletions go/vt/vtgate/vtgate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"strings"
"testing"

"vitess.io/vitess/go/test/utils"

"context"

"github.com/golang/protobuf/proto"
Expand Down Expand Up @@ -207,9 +209,7 @@ func TestVTGateStreamExecute(t *testing.T) {
}, {
Rows: sandboxconn.StreamRowResult.Rows,
}}
if !reflect.DeepEqual(want, qrs) {
t.Errorf("want \n%+v, got \n%+v", want, qrs)
}
utils.MustMatch(t, want, qrs)
if !proto.Equal(sbc.Options[0], executeOptions) {
t.Errorf("got ExecuteOptions \n%+v, want \n%+v", sbc.Options[0], executeOptions)
}
Expand Down
23 changes: 21 additions & 2 deletions go/vt/vttablet/sandboxconn/sandboxconn.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,15 @@ func (sbc *SandboxConn) getNextResult(stmt sqlparser.Statement) *sqltypes.Result
}
if stmt == nil {
// if we didn't get a valid query, we'll assume we need a SELECT
return SingleRowResult
return getSingleRowResult()
}
switch stmt.(type) {
case *sqlparser.Select,
*sqlparser.Union,
*sqlparser.Show,
sqlparser.Explain,
*sqlparser.OtherRead:
return SingleRowResult
return getSingleRowResult()
case *sqlparser.Set,
sqlparser.DDLStatement,
*sqlparser.AlterVschema,
Expand Down Expand Up @@ -551,6 +551,25 @@ func (sbc *SandboxConn) StringQueries() []string {
return result
}

// getSingleRowResult is used to get a SingleRowResult but it creates separate fields because some tests change the fields
// If these fields are not created separately then the constants value also changes which leads to some other tests failing later
func getSingleRowResult() *sqltypes.Result {
singleRowResult := &sqltypes.Result{
InsertID: SingleRowResult.InsertID,
StatusFlags: SingleRowResult.StatusFlags,
Rows: SingleRowResult.Rows,
}

for _, field := range SingleRowResult.Fields {
singleRowResult.Fields = append(singleRowResult.Fields, &querypb.Field{
Name: field.Name,
Type: field.Type,
})
}

return singleRowResult
}

// SingleRowResult is returned when there is no pre-stored result.
var SingleRowResult = &sqltypes.Result{
Fields: []*querypb.Field{
Expand Down

0 comments on commit 5dee786

Please sign in to comment.