Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe table to route based on table name and qualifier #7445

Merged
merged 8 commits into from
Feb 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions go/test/endtoend/vtgate/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ func TestExplainPassthrough(t *testing.T) {
got := fmt.Sprintf("%v", result.Rows)
require.Contains(t, got, "SIMPLE") // there is a lot more coming from mysql,
// but we are trying to make the test less fragile

result = exec(t, conn, "explain ks.t1")
require.EqualValues(t, 2, len(result.Rows))
}

func TestXXHash(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion go/vt/sqlparser/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func ASTToStatementType(stmt Statement) StatementType {
return StmtUse
case *OtherRead, *OtherAdmin, *Load:
return StmtOther
case *Explain:
case Explain:
return StmtExplain
case *Begin:
return StmtBegin
Expand Down
71 changes: 47 additions & 24 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ type (

// SelectStatement any SELECT statement.
SelectStatement interface {
Statement
iSelectStatement()
iStatement()
iInsertRows()
AddOrder(*Order)
SetLimit(*Limit)
SetLock(lock Lock)
MakeDistinct()
SQLNode
}

// DDLStatement represents any DDL Statement
Expand Down Expand Up @@ -86,6 +85,12 @@ type (
SQLNode
}

// Explain is an interface that represents the Explain statements
Explain interface {
Statement
harshit-gangal marked this conversation as resolved.
Show resolved Hide resolved
iExplain()
}

// AddConstraintDefinition represents a ADD CONSTRAINT alter option
AddConstraintDefinition struct {
ConstraintDefinition *ConstraintDefinition
Expand Down Expand Up @@ -505,32 +510,12 @@ type (
Name ColIdent
}

// Explain represents an EXPLAIN statement
Explain struct {
Type ExplainType
Statement Statement
}

// ExplainType is an enum for Explain.Type
ExplainType int8

// CallProc represents a CALL statement
CallProc struct {
Name TableName
Params Exprs
}

// OtherRead represents a DESCRIBE, or EXPLAIN statement.
// It should be used only as an indicator. It does not contain
// the full AST for the statement.
OtherRead struct{}

// OtherAdmin represents a misc statement that relies on ADMIN privileges,
// such as REPAIR, OPTIMIZE, or TRUNCATE statement.
// It should be used only as an indicator. It does not contain
// the full AST for the statement.
OtherAdmin struct{}

// LockType is an enum for Lock Types
LockType int8

Expand All @@ -550,6 +535,32 @@ type (

// UnlockTables represents the unlock statement
UnlockTables struct{}

// ExplainType is an enum for ExplainStmt.Type
ExplainType int8

// ExplainStmt represents an Explain statement
ExplainStmt struct {
Type ExplainType
Statement Statement
}

// ExplainTab represents the Explain table
ExplainTab struct {
Table TableName
Wild string
}

// OtherRead represents a DESCRIBE, or EXPLAIN statement.
// It should be used only as an indicator. It does not contain
// the full AST for the statement.
OtherRead struct{}

// OtherAdmin represents a misc statement that relies on ADMIN privileges,
// such as REPAIR, OPTIMIZE, or TRUNCATE statement.
// It should be used only as an indicator. It does not contain
// the full AST for the statement.
OtherAdmin struct{}
)

func (*Union) iStatement() {}
Expand All @@ -571,7 +582,6 @@ func (*Rollback) iStatement() {}
func (*SRollback) iStatement() {}
func (*Savepoint) iStatement() {}
func (*Release) iStatement() {}
func (*Explain) iStatement() {}
func (*OtherRead) iStatement() {}
func (*OtherAdmin) iStatement() {}
func (*Select) iSelectStatement() {}
Expand All @@ -592,6 +602,8 @@ func (*DropView) iStatement() {}
func (*TruncateTable) iStatement() {}
func (*RenameTable) iStatement() {}
func (*CallProc) iStatement() {}
func (*ExplainStmt) iStatement() {}
func (*ExplainTab) iStatement() {}

func (*CreateView) iDDLStatement() {}
func (*AlterView) iDDLStatement() {}
Expand Down Expand Up @@ -622,6 +634,9 @@ func (*RenameIndex) iAlterOption() {}
func (*Validation) iAlterOption() {}
func (TableOptions) iAlterOption() {}

func (*ExplainStmt) iExplain() {}
func (*ExplainTab) iExplain() {}

// IsFullyParsed implements the DDLStatement interface
func (*TruncateTable) IsFullyParsed() bool {
return true
Expand Down Expand Up @@ -2486,7 +2501,7 @@ func (node *Release) Format(buf *TrackedBuffer) {
}

// Format formats the node.
func (node *Explain) Format(buf *TrackedBuffer) {
func (node *ExplainStmt) Format(buf *TrackedBuffer) {
format := ""
switch node.Type {
case EmptyType: // do nothing
Expand All @@ -2498,6 +2513,14 @@ func (node *Explain) Format(buf *TrackedBuffer) {
buf.astPrintf(node, "explain %s%v", format, node.Statement)
}

// Format formats the node.
func (node *ExplainTab) Format(buf *TrackedBuffer) {
buf.astPrintf(node, "explain %v", node.Table)
if node.Wild != "" {
buf.astPrintf(node, " %s", node.Wild)
}
}

// Format formats the node.
func (node *CallProc) Format(buf *TrackedBuffer) {
buf.astPrintf(node, "call %v(%v)", node.Name, node.Params)
Expand Down
10 changes: 5 additions & 5 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1534,13 +1534,13 @@ var (
output: "explain select * from t",
}, {
input: "desc foobar",
output: "otherread",
output: "explain foobar",
}, {
input: "explain t1",
output: "otherread",
input: "explain t1",
}, {
input: "explain t1 col",
output: "otherread",
input: "explain t1 col",
}, {
input: "explain t1 '%col%'",
}, {
input: "explain select * from t",
}, {
Expand Down
15 changes: 11 additions & 4 deletions go/vt/sqlparser/rewriter.go

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

8 changes: 4 additions & 4 deletions go/vt/sqlparser/sql.go

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

10 changes: 5 additions & 5 deletions go/vt/sqlparser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -2728,21 +2728,21 @@ wild_opt:
}
| sql_id
{
$$ = ""
$$ = $1.val
}
| STRING
{
$$ = ""
$$ = "'" + string($1) + "'"
}

explain_statement:
explain_synonyms table_name wild_opt
{
$$ = &OtherRead{}
$$ = &ExplainTab{Table: $2, Wild: $3}
}
| explain_synonyms explain_format_opt explainable_statement
{
$$ = &Explain{Type: $2, Statement: $3}
$$ = &ExplainStmt{Type: $2, Statement: $3}
}

other_statement:
Expand Down
39 changes: 19 additions & 20 deletions go/vt/vtgate/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1035,27 +1035,26 @@ func TestExecutorOther(t *testing.T) {

for _, stmt := range stmts {
for _, tc := range tcs {
sbc1.ExecCount.Set(0)
sbc2.ExecCount.Set(0)
sbclookup.ExecCount.Set(0)

_, err := executor.Execute(ctx, "TestExecute", NewSafeSession(&vtgatepb.Session{TargetString: tc.targetStr}), stmt, nil)
if tc.hasNoKeyspaceErr {
assert.Error(t, err, errNoKeyspace)
} else if tc.hasDestinationShardErr {
assert.Errorf(t, err, "Destination can only be a single shard for statement: %s, got: DestinationExactKeyRange(-)", stmt)
} else {
assert.NoError(t, err)
}

diff := cmp.Diff(tc.wantCnts, cnts{
Sbc1Cnt: sbc1.ExecCount.Get(),
Sbc2Cnt: sbc2.ExecCount.Get(),
SbcLookupCnt: sbclookup.ExecCount.Get(),
t.Run(fmt.Sprintf("%s-%s", stmt, tc.targetStr), func(t *testing.T) {
sbc1.ExecCount.Set(0)
sbc2.ExecCount.Set(0)
sbclookup.ExecCount.Set(0)

_, err := executor.Execute(ctx, "TestExecute", NewSafeSession(&vtgatepb.Session{TargetString: tc.targetStr}), stmt, nil)
if tc.hasNoKeyspaceErr {
assert.Error(t, err, errNoKeyspace)
} else if tc.hasDestinationShardErr {
assert.Errorf(t, err, "Destination can only be a single shard for statement: %s", stmt)
} else {
assert.NoError(t, err)
}

utils.MustMatch(t, tc.wantCnts, cnts{
Sbc1Cnt: sbc1.ExecCount.Get(),
Sbc2Cnt: sbc2.ExecCount.Get(),
SbcLookupCnt: sbclookup.ExecCount.Get(),
})
})
if diff != "" {
t.Errorf("stmt: %s\ntc: %+v\n-want,+got:\n%s", stmt, tc, diff)
}
}
}
}
Expand Down
11 changes: 2 additions & 9 deletions go/vt/vtgate/planbuilder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,8 @@ func createInstructionFor(query string, stmt sqlparser.Statement, vschema Contex
return buildVSchemaDDLPlan(stmt, vschema)
case *sqlparser.Use:
return buildUsePlan(stmt, vschema)
case *sqlparser.Explain:
if stmt.Type == sqlparser.VitessType {
innerInstruction, err := createInstructionFor(query, stmt.Statement, vschema)
if err != nil {
return nil, err
}
return buildExplainPlan(innerInstruction)
}
return buildOtherReadAndAdmin(query, vschema)
case sqlparser.Explain:
return buildExplainPlan(stmt, vschema)
case *sqlparser.OtherRead, *sqlparser.OtherAdmin:
return buildOtherReadAndAdmin(query, vschema)
case *sqlparser.Set:
Expand Down
Loading