Skip to content

Commit

Permalink
show table rules (arana-db#760)
Browse files Browse the repository at this point in the history
  • Loading branch information
binbin0325 authored Sep 30, 2023
1 parent 81397b5 commit ac511fe
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 18 deletions.
5 changes: 3 additions & 2 deletions pkg/executor/redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,9 @@ func (executor *RedirectExecutor) doExecutorComQuery(ctx *proto.Context, act ast
allowSchemaless := func(stmt *ast.ShowStmt) bool {
switch stmt.Tp {
case ast.ShowDatabases, ast.ShowVariables, ast.ShowTopology, ast.ShowStatus, ast.ShowTableStatus,
ast.ShowWarnings, ast.ShowCharset, ast.ShowMasterStatus, ast.ShowProcessList, ast.ShowReplicas, ast.ShowShardingTable,
ast.ShowReplicaStatus, ast.ShowNodes, ast.ShowUsers, ast.ShowCreateSequence, ast.ShowDatabaseRules:
ast.ShowWarnings, ast.ShowCharset, ast.ShowMasterStatus, ast.ShowProcessList, ast.ShowReplicas,
ast.ShowShardingTable, ast.ShowReplicaStatus, ast.ShowNodes, ast.ShowUsers, ast.ShowCreateSequence,
ast.ShowDatabaseRules, ast.ShowTableRules:
return true
default:
return false
Expand Down
8 changes: 8 additions & 0 deletions pkg/mysql/thead/thead.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ var (
Col{Name: "expr", FieldType: consts.FieldTypeVarString},
Col{Name: "step", FieldType: consts.FieldTypeInt24},
}

TableRule = Thead{
Col{Name: "table_name", FieldType: consts.FieldTypeVarString},
Col{Name: "column", FieldType: consts.FieldTypeVarString},
Col{Name: "type", FieldType: consts.FieldTypeVarString},
Col{Name: "expr", FieldType: consts.FieldTypeVarString},
Col{Name: "step", FieldType: consts.FieldTypeVarString},
}
)

type Col struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/runtime/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,8 @@ func (cc *convCtx) convShowStmt(node *ast.ShowStmt) Statement {
pattern.String = like
}
return &ShowDatabases{BaseShowWithSingleColumn: &BaseShowWithSingleColumn{toBaseShow(), pattern}}
case ast.ShowTableRules:
return &ShowTableRule{BaseShow: toBaseShow(), Database: node.DBName, TableName: node.Table.Name.String()}
case ast.ShowDatabaseRules:
return &ShowDatabaseRule{BaseShow: toBaseShow(), Database: node.DBName, TableName: node.Table.Name.String()}
case ast.ShowCollation:
Expand Down
2 changes: 2 additions & 0 deletions pkg/runtime/ast/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const (
SQLTypeRepairTable // REPAIR TABLE
SQLTypeCreateTable // CREATE TABLE
SQLTypeShowDatabaseRules // SHOW DATABASE RULES
SQLTypeShowTableRules // SHOW TABLE RULES
)

var _sqlTypeNames = [...]string{
Expand Down Expand Up @@ -108,6 +109,7 @@ var _sqlTypeNames = [...]string{
SQLTypeRepairTable: "REPAIR TABLE",
SQLTypeCreateTable: "CREATE TABLE",
SQLTypeShowDatabaseRules: "SHOW DATABASE RULES",
SQLTypeShowTableRules: "SHOW TABLE RULES",
}

// SQLType represents the type of SQL.
Expand Down
22 changes: 20 additions & 2 deletions pkg/runtime/ast/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,14 +670,32 @@ type ShowDatabaseRule struct {
TableName string
}

func (s ShowDatabaseRule) Mode() SQLType {
func (s *ShowDatabaseRule) Mode() SQLType {
return SQLTypeShowDatabaseRules
}

func (s ShowDatabaseRule) Restore(flag RestoreFlag, sb *strings.Builder, args *[]int) error {
func (s *ShowDatabaseRule) Restore(flag RestoreFlag, sb *strings.Builder, args *[]int) error {
sb.WriteString("SHOW DATABASE RULES ")
if err := s.BaseShow.Restore(flag, sb, args); err != nil {
return errors.WithStack(err)
}
return nil
}

type ShowTableRule struct {
*BaseShow
Database string
TableName string
}

func (s *ShowTableRule) Mode() SQLType {
return SQLTypeShowTableRules
}

func (s *ShowTableRule) Restore(flag RestoreFlag, sb *strings.Builder, args *[]int) error {
sb.WriteString("SHOW TABLE RULES ")
if err := s.BaseShow.Restore(flag, sb, args); err != nil {
return errors.WithStack(err)
}
return nil
}
42 changes: 42 additions & 0 deletions pkg/runtime/optimize/dal/show_table_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 dal

import (
"context"
)

import (
"github.com/arana-db/arana/pkg/proto"
"github.com/arana-db/arana/pkg/runtime/ast"
"github.com/arana-db/arana/pkg/runtime/optimize"
"github.com/arana-db/arana/pkg/runtime/plan/dal"
)

func init() {
optimize.Register(ast.SQLTypeShowTableRules, optimizeShowTableRules)
}

func optimizeShowTableRules(_ context.Context, o *optimize.Optimizer) (proto.Plan, error) {
rule := o.Rule
stmt := o.Stmt.(*ast.ShowTableRule)
ret := dal.NewShowTableRulesPlan(stmt)
ret.BindArgs(o.Args)
ret.SetRule(rule)
return ret, nil
}
30 changes: 16 additions & 14 deletions pkg/runtime/plan/dal/show_database_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,24 @@ func (s *ShowDatabaseRulesPlan) ExecIn(ctx context.Context, _ proto.VConn) (prot
Columns: fields,
}

if vt, ok := s.rule.VTable(s.Stmt.TableName); ok {
for _, vs := range vt.GetVShards() {
var columns []string
for i := range vs.DB.ShardColumns {
columns = append(columns, vs.DB.ShardColumns[i].Name)
}
ds.Rows = append(ds.Rows, rows.NewTextVirtualRow(fields, []proto.Value{
proto.NewValueString(s.Stmt.TableName),
proto.NewValueString(strings.Join(columns, ",")),
proto.NewValueString(""),
proto.NewValueString(fmt.Sprintf("%s", vs.DB.Computer)),
proto.NewValueInt64(1),
}))
}
vt, ok := s.rule.VTable(s.Stmt.TableName)
if !ok {
return resultx.New(resultx.WithDataset(ds)), nil
}

for _, vs := range vt.GetVShards() {
var columns []string
for i := range vs.DB.ShardColumns {
columns = append(columns, vs.DB.ShardColumns[i].Name)
}
ds.Rows = append(ds.Rows, rows.NewTextVirtualRow(fields, []proto.Value{
proto.NewValueString(s.Stmt.TableName),
proto.NewValueString(strings.Join(columns, ",")),
proto.NewValueString(""),
proto.NewValueString(fmt.Sprintf("%s", vs.DB.Computer)),
proto.NewValueInt64(1),
}))
}
return resultx.New(resultx.WithDataset(ds)), nil
}

Expand Down
95 changes: 95 additions & 0 deletions pkg/runtime/plan/dal/show_table_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 dal

import (
"context"
"fmt"
"strconv"
"strings"
)

import (
"github.com/arana-db/arana/pkg/dataset"
"github.com/arana-db/arana/pkg/mysql/rows"
"github.com/arana-db/arana/pkg/mysql/thead"
"github.com/arana-db/arana/pkg/proto"
"github.com/arana-db/arana/pkg/proto/rule"
"github.com/arana-db/arana/pkg/resultx"
"github.com/arana-db/arana/pkg/runtime/ast"
"github.com/arana-db/arana/pkg/runtime/plan"
)

var _ proto.Plan = (*ShowTableRulesPlan)(nil)

type ShowTableRulesPlan struct {
plan.BasePlan
Stmt *ast.ShowTableRule
rule *rule.Rule
}

func (s *ShowTableRulesPlan) Type() proto.PlanType {
return proto.PlanTypeQuery
}

func (s *ShowTableRulesPlan) ExecIn(ctx context.Context, _ proto.VConn) (proto.Result, error) {
_, span := plan.Tracer.Start(ctx, "ShowTableRulesPlan.ExecIn")
defer span.End()

fields := thead.TableRule.ToFields()
ds := &dataset.VirtualDataset{
Columns: fields,
}
vt, ok := s.rule.VTable(s.Stmt.TableName)
if !ok {
return resultx.New(resultx.WithDataset(ds)), nil
}

for _, vs := range vt.GetVShards() {
var (
columns []string
steps []string
)

for i := range vs.Table.ShardColumns {
columns = append(columns, vs.Table.ShardColumns[i].Name)
steps = append(steps, strconv.Itoa(vs.Table.ShardColumns[i].Steps))
}

ds.Rows = append(ds.Rows, rows.NewTextVirtualRow(fields, []proto.Value{
proto.NewValueString(s.Stmt.TableName),
proto.NewValueString(strings.Join(columns, ",")),
proto.NewValueString(""),
proto.NewValueString(fmt.Sprintf("%s", vs.Table.Computer)),
proto.NewValueString(strings.Join(steps, ",")),
}))
}

return resultx.New(resultx.WithDataset(ds)), nil
}

func (s *ShowTableRulesPlan) SetRule(rule *rule.Rule) {
s.rule = rule
}

// NewShowTableRulesPlan create ShowTableRules Plan
func NewShowTableRulesPlan(stmt *ast.ShowTableRule) *ShowTableRulesPlan {
return &ShowTableRulesPlan{
Stmt: stmt,
}
}
33 changes: 33 additions & 0 deletions test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,39 @@ func (s *IntegrationSuite) TestShowDatabaseRules() {
}
}

func (s *IntegrationSuite) TestShowTableRules() {
var (
db = s.DB()
t = s.T()
)

tests := []struct {
name string
sql string
expectNum int
}{
{
name: "show table rules from employees",
sql: "show table rules from employees",
expectNum: 0,
},
{
name: "show table rules from student",
sql: "show table rules from student",
expectNum: 1,
},
}

for _, v := range tests {
rows, err := db.Query(v.sql)
defer rows.Close()
assert.NoErrorf(t, err, "show table rules error: %v", err)
results, err := utils.PrintTable(rows)
assert.NoErrorf(t, err, "show table rules error: %v", err)
assert.Equal(t, len(results), v.expectNum)
}
}

func (s *IntegrationSuite) TestDropTrigger() {
var (
db = s.DB()
Expand Down

0 comments on commit ac511fe

Please sign in to comment.