Skip to content

Commit

Permalink
router: add partition list radondb#491
Browse files Browse the repository at this point in the history
[summary]
router add partition list

[test case]
src/router/compute_test.go
src/router/frm_test.go
src/router/list_test.go
src/router/router_test.go

[patch codecov]
src/router/compute.go 100%
src/router/frm.go 79.1%
src/router/list.go 93.3%
src/router/router.go 93.3%
  • Loading branch information
andyli029 committed Oct 23, 2019
1 parent e21c8f7 commit 17f7269
Show file tree
Hide file tree
Showing 13 changed files with 566 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/proxy/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (spanner *Spanner) handleDDL(session *driver.Session, query string, node *s
table := ddl.Table.Name.String()
backends := scatter.Backends()
shardKey := ddl.PartitionName
tableType := router.TableTypeUnknow
tableType := router.TableTypeUnknown

if !checkDatabaseExists(database, route) {
return nil, sqldb.NewSQLError(sqldb.ER_BAD_DB_ERROR, database)
Expand Down
60 changes: 60 additions & 0 deletions src/router/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"config"

"github.com/pkg/errors"
"github.com/xelabs/go-mysqlstack/sqlparser"
"github.com/xelabs/go-mysqlstack/sqlparser/depends/common"
)

// HashUniform used to uniform the hash slots to backends.
Expand Down Expand Up @@ -120,3 +122,61 @@ func (r *Router) SingleUniform(table string, backends []string) (*config.TableCo
}},
}, nil
}

func listMergePartition(partitionDef sqlparser.PartitionOptions) (map[string]string, error) {
partitionMap := make(map[string]string)
for _, onePart := range partitionDef {
row := onePart.Row
valuesNum := len(row)
for i := 0; i < valuesNum; i++ {
key := common.BytesToString(row[i].(*sqlparser.SQLVal).Val)
if _, ok := partitionMap[key]; !ok {
partitionMap[key] = onePart.Backend
} else {
if partitionMap[key] != onePart.Backend {
return nil, errors.New("partition.list.different.backend.with.same.values.")
}
}
}
}
return partitionMap, nil
}

// ListUniform used to uniform the list table to backends.
func (r *Router) ListUniform(table string, shardkey string, partitionDef sqlparser.PartitionOptions) (*config.TableConfig, error) {
if table == "" {
return nil, errors.New("table.cant.be.null")
}
if shardkey == "" {
return nil, errors.New("shard.key.cant.be.null")
}

listMap, err := listMergePartition(partitionDef)
if err != nil {
return nil, err
}

nums := len(listMap)
if nums == 0 {
return nil, errors.New("router.compute.partition.list.is.null")
}

tableConf := &config.TableConfig{
Name: table,
ShardType: methodTypeList,
ShardKey: shardkey,
Partitions: make([]*config.PartitionConfig, 0, 16),
}

i := 0
for listValue, backend := range listMap {
partConf := &config.PartitionConfig{
Table: fmt.Sprintf("%s_%04d", table, i),
Backend: backend,
ListValue: listValue,
}
tableConf.Partitions = append(tableConf.Partitions, partConf)
i++
}
return tableConf, nil
}
99 changes: 99 additions & 0 deletions src/router/compute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"config"

"github.com/stretchr/testify/assert"
"github.com/xelabs/go-mysqlstack/sqlparser"
"github.com/xelabs/go-mysqlstack/xlog"
)

Expand Down Expand Up @@ -355,3 +356,101 @@ func TestRouterComputeSingleError(t *testing.T) {
assert.NotNil(t, err)
}
}

func TestRouterComputeListError(t *testing.T) {
log := xlog.NewStdLog(xlog.Level(xlog.PANIC))
router, cleanup := MockNewRouter(log)
defer cleanup()

// Shardkey is NULL.
{
assert.NotNil(t, router)
_, err := router.ListUniform("t1", "", sqlparser.PartitionOptions{})
assert.NotNil(t, err)
}

// Table is NULL.
{
assert.NotNil(t, router)
_, err := router.ListUniform("", "i", sqlparser.PartitionOptions{})
assert.NotNil(t, err)
}

// different backends with same list value.
{
partitionDef := sqlparser.PartitionOptions{
&sqlparser.PartitionDefinition{
Backend: "node1",
Row: sqlparser.ValTuple{sqlparser.NewStrVal([]byte("1"))},
},
&sqlparser.PartitionDefinition{
Backend: "node2",
Row: sqlparser.ValTuple{sqlparser.NewIntVal([]byte("1"))},
},
}

assert.NotNil(t, router)
_, err := router.ListUniform("t1", "i", partitionDef)
assert.NotNil(t, err)
}

// empty PartitionOptions
{
assert.NotNil(t, router)
_, err := router.ListUniform("t1", "i", sqlparser.PartitionOptions{})
assert.NotNil(t, err)
}
}

func TestRouterComputeList1(t *testing.T) {
datas := `{
"name": "l",
"shardtype": "LIST",
"shardkey": "id",
"partitions": [
{
"table": "l_0000",
"segment": "",
"backend": "node1",
"listvalue": "2"
},
{
"table": "l_0001",
"segment": "",
"backend": "node2",
"listvalue": "4"
},
{
"table": "l_0002",
"segment": "",
"backend": "node3",
"listvalue": "6"
}
]
}`
log := xlog.NewStdLog(xlog.Level(xlog.PANIC))
router, cleanup := MockNewRouter(log)
defer cleanup()
assert.NotNil(t, router)

partitionDef := sqlparser.PartitionOptions{
&sqlparser.PartitionDefinition{
Backend: "node1",
Row: sqlparser.ValTuple{sqlparser.NewStrVal([]byte("2"))},
},
&sqlparser.PartitionDefinition{
Backend: "node2",
Row: sqlparser.ValTuple{sqlparser.NewIntVal([]byte("4"))},
},
&sqlparser.PartitionDefinition{
Backend: "node3",
Row: sqlparser.ValTuple{sqlparser.NewIntVal([]byte("6"))},
},
}

got, err := router.ListUniform("l", "id", partitionDef)
assert.Nil(t, err)
want, err := config.ReadTableConfig(datas)
assert.Nil(t, err)
assert.EqualValues(t, want, got)
}
48 changes: 45 additions & 3 deletions src/router/frm.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import (
"config"

"github.com/pkg/errors"
"github.com/xelabs/go-mysqlstack/sqlparser"
)

const (
TableTypeSingle = "single"
TableTypeGlobal = "global"
TableTypeUnknow = "unknow"
TableTypeSingle = "single"
TableTypeGlobal = "global"
TableTypeUnknown = "unknown"

TableTypePartitionHash = "hash"
TableTypePartitionList = "list"
Expand Down Expand Up @@ -251,6 +252,47 @@ func (r *Router) CreateTable(db, table, shardKey string, tableType string, backe
return nil
}

func (r *Router) CreateListTable(db, table, shardKey string, tableType string,
partitionDef sqlparser.PartitionOptions, extra *Extra) error {
r.mu.Lock()
defer r.mu.Unlock()

var err error
var tableConf *config.TableConfig
log := r.log

switch tableType {
case TableTypePartitionList:
if tableConf, err = r.ListUniform(table, shardKey, partitionDef); err != nil {
return err
}

default:
err := errors.Errorf("tableType is unsupported: %s", tableType)
return err
}

if extra != nil {
tableConf.AutoIncrement = extra.AutoIncrement
}

// add config to router.
if err = r.addTable(db, tableConf); err != nil {
log.Error("frm.create.add.route.error:%v", err)
return err
}
if err = r.writeTableFrmData(db, table, tableConf); err != nil {
log.Error("frm.create.table[db:%v, table:%v].file.error:%+v", db, tableConf.Name, err)
return err
}

if err = config.UpdateVersion(r.metadir); err != nil {
log.Panicf("frm.create.table.update.version.error:%v", err)
return err
}
return nil
}

func (r *Router) createTable(db, table string, tableConf *config.TableConfig) error {
var err error

Expand Down
18 changes: 18 additions & 0 deletions src/router/frm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/xelabs/go-mysqlstack/sqlparser"
"github.com/xelabs/go-mysqlstack/xlog"
)

Expand Down Expand Up @@ -82,6 +83,23 @@ func TestFrmTable(t *testing.T) {
assert.Nil(t, err)
}

// Add list table.
{
partitionDef := sqlparser.PartitionOptions{
&sqlparser.PartitionDefinition{
Backend: "node1",
Row: sqlparser.ValTuple{sqlparser.NewStrVal([]byte("2"))},
},
&sqlparser.PartitionDefinition{
Backend: "node2",
Row: sqlparser.ValTuple{sqlparser.NewIntVal([]byte("4"))},
},
}

err := router.CreateListTable("test", "l", "id", TableTypePartitionList, partitionDef, nil)
assert.Nil(t, err)
}

// Add partition table.
{
backends := []string{"backend1", "backend2"}
Expand Down
Loading

0 comments on commit 17f7269

Please sign in to comment.