Skip to content

Commit

Permalink
feat: in sharding mode support show tables (#267)
Browse files Browse the repository at this point in the history
* feat: in sharding mode support show tables
  • Loading branch information
dk-lockdown authored Oct 7, 2022
1 parent dc372d9 commit 1c353ea
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 0 deletions.
45 changes: 45 additions & 0 deletions pkg/optimize/optimize_show_tables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2022 CECTC, 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 optimize

import (
"context"

"github.com/pkg/errors"

"github.com/cectc/dbpack/pkg/plan"
"github.com/cectc/dbpack/pkg/proto"
"github.com/cectc/dbpack/third_party/parser/ast"
)

func (o Optimizer) optimizeShowTables(ctx context.Context, stmt *ast.ShowStmt, args []interface{}) (proto.Plan, error) {
var logicTables []string
if stmt.Tp != ast.ShowTables {
return nil, errors.New("statement must be show tables stmt")
}

for logicTable := range o.topologies {
logicTables = append(logicTables, logicTable)
}

return &plan.ShowTablesPlan{
Stmt: stmt,
Args: args,
Executor: o.executors[0],
LogicTables: logicTables,
}, nil
}
2 changes: 2 additions & 0 deletions pkg/optimize/optimizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func (o Optimizer) Optimize(ctx context.Context, stmt ast.StmtNode, args ...inte
switch t.Tp {
case ast.ShowTableStatus:
return o.optimizeShowTableStatus(ctx, t, args)
case ast.ShowTables:
return o.optimizeShowTables(ctx, t, args)
case ast.ShowColumns, ast.ShowIndex:
return o.optimizeShowTableMeta(ctx, t, args)
}
Expand Down
101 changes: 101 additions & 0 deletions pkg/plan/show_tables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright 2022 CECTC, 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 (
"context"
"regexp"
"strings"

"github.com/pkg/errors"

"github.com/cectc/dbpack/pkg/constant"
"github.com/cectc/dbpack/pkg/mysql"
"github.com/cectc/dbpack/pkg/proto"
"github.com/cectc/dbpack/third_party/parser/ast"
"github.com/cectc/dbpack/third_party/parser/format"
)

const (
tableNameRegex = `^(\w+)_(\d+)$`
)

var (
tableNameRegexp = regexp.MustCompile(tableNameRegex)
)

type ShowTablesPlan struct {
Stmt *ast.ShowStmt
Args []interface{}
Executor proto.DBGroupExecutor
LogicTables []string
}

func (p *ShowTablesPlan) Execute(ctx context.Context, _ ...*ast.TableOptimizerHint) (proto.Result, uint16, error) {
var (
sb strings.Builder
sql string
result proto.Result
warns uint16
err error
)
restoreCtx := format.NewRestoreCtx(constant.DBPackRestoreFormat, &sb)
if err = p.Stmt.Restore(restoreCtx); err != nil {
return nil, 0, errors.WithStack(err)
}
sql = sb.String()

result, warns, err = p.Executor.Query(ctx, sql)
if err != nil {
return nil, 0, err
}
mysqlResult := result.(*mysql.Result)
rows := make([]proto.Row, 0)
rowMap := make(map[string]struct{})
for _, row := range mysqlResult.Rows {
if _, err := row.Decode(); err != nil {
return nil, 0, err
}
textRow := row.(*mysql.TextRow)
table, filtered := filterTable(string(textRow.Values[0].Val.([]byte)), p.LogicTables)
if filtered {
textRow.Values[0].Val = []byte(table)
}
if _, exist := rowMap[table]; !exist {
rows = append(rows, textRow)
rowMap[table] = struct{}{}
}
}
return &mysql.Result{
Fields: mysqlResult.Fields,
AffectedRows: mysqlResult.AffectedRows,
InsertId: mysqlResult.InsertId,
Rows: rows,
}, warns, nil
}

// filterTable return table, filtered
func filterTable(table string, logicTables []string) (string, bool) {
for _, logicTable := range logicTables {
if tableNameRegexp.MatchString(table) {
if strings.Contains(table, logicTable) {
return logicTable, true
}
}
}
return table, false
}
14 changes: 14 additions & 0 deletions test/shd/sharding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,20 @@ func (suite *_ShardingSuite) TestShowTableStatus() {
}
}

func (suite *_ShardingSuite) TestShowTables() {
rows, err := suite.db.Query("SHOW TABLES")
if suite.NoErrorf(err, "show tables error: %v", err) {
var (
table string
)
for rows.Next() {
err := rows.Scan(&table)
suite.NoError(err)
suite.T().Logf("%s", table)
}
}
}

func (suite *_ShardingSuite) TestShowTableMeta() {
rows, err := suite.db.Query("SHOW COLUMNS FROM city")
if suite.NoErrorf(err, "show columns error: %v", err) {
Expand Down

0 comments on commit 1c353ea

Please sign in to comment.