Skip to content

Commit

Permalink
Add 'SHOW realtions' method to console (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
EinKrebs authored Feb 26, 2024
1 parent d7e2d99 commit 2ffa216
Show file tree
Hide file tree
Showing 13 changed files with 613 additions and 300 deletions.
61 changes: 60 additions & 1 deletion pkg/clientinteractor/interactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package clientinteractor
import (
"context"
"fmt"
"github.com/pg-sharding/spqr/pkg/models/hashfunction"
"net"
"sort"
"strconv"
"strings"

Expand Down Expand Up @@ -370,7 +372,7 @@ func MatchRow(row []string, nameToIndex map[string]int, condition spqrparser.Whe
case "=":
i, ok := nameToIndex[where.ColRef.ColName]
if !ok {
return true, spqrerror.Newf(spqrerror.SPQR_COMPLEX_QUERY, "column %s not exists", where.ColRef.ColName)
return true, spqrerror.Newf(spqrerror.SPQR_COMPLEX_QUERY, "column %s does not exist", where.ColRef.ColName)
}
return row[i] == where.Value, nil
default:
Expand Down Expand Up @@ -868,3 +870,60 @@ func (pi *PSQLInteractor) BackendConnections(ctx context.Context, shs []shard.Sh

return pi.CompleteMsg(len(shs))
}

// Relations sends information about attached relations that satisfy conditions in WHERE-clause
// TODO unit tests
func (pi *PSQLInteractor) Relations(dsToRels map[string][]*distributions.DistributedRelation, condition spqrparser.WhereClauseNode) error {
if err := pi.cl.Send(&pgproto3.RowDescription{Fields: []pgproto3.FieldDescription{
TextOidFD("Relation name"),
TextOidFD("Distribution ID"),
TextOidFD("Distribution key"),
}}); err != nil {
spqrlog.Zero.Error().Err(err).Msg("")
return err
}

dss := make([]string, len(dsToRels))
i := 0
for ds := range dsToRels {
dss[i] = ds
i++
}
sort.Strings(dss)

c := 0
index := map[string]int{"distribution_id": 0}
for _, ds := range dss {
rels := dsToRels[ds]
sort.Slice(rels, func(i, j int) bool {
return rels[i].Name < rels[j].Name
})
if ok, err := MatchRow([]string{ds}, index, condition); err != nil {
return err
} else if !ok {
continue
}
for _, rel := range rels {
dsKey := make([]string, len(rel.DistributionKey))
for i, e := range rel.DistributionKey {
t, err := hashfunction.HashFunctionByName(e.HashFunction)
if err != nil {
return err
}
dsKey[i] = fmt.Sprintf("(\"%s\", %s)", e.Column, hashfunction.ToString(t))
}
if err := pi.cl.Send(&pgproto3.DataRow{
Values: [][]byte{
[]byte(rel.Name),
[]byte(ds),
[]byte(strings.Join(dsKey, ",")),
},
}); err != nil {
spqrlog.Zero.Error().Err(err).Msg("")
return err
}
c++
}
}
return pi.CompleteMsg(c)
}
21 changes: 19 additions & 2 deletions pkg/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,28 @@ func ProcessShow(ctx context.Context, stmt *spqrparser.Show, mngr EntityMgr, ci
case spqrparser.VersionStr:
return cli.Version(ctx)
case spqrparser.DistributionsStr:
distributions, err := mngr.ListDistributions(ctx)
dss, err := mngr.ListDistributions(ctx)
if err != nil {
return err
}
return cli.Distributions(ctx, dss)
case spqrparser.RelationsStr:
dss, err := mngr.ListDistributions(ctx)
if err != nil {
return err
}
return cli.Distributions(ctx, distributions)
dsToRels := make(map[string][]*distributions.DistributedRelation)
for _, ds := range dss {
if _, ok := dsToRels[ds.Id]; ok {
return spqrerror.Newf(spqrerror.SPQR_METADATA_CORRUPTION, "Duplicate values on \"%s\" distribution ID", ds.Id)
}
dsToRels[ds.Id] = make([]*distributions.DistributedRelation, 0)
for _, rel := range ds.Relations {
dsToRels[ds.Id] = append(dsToRels[ds.Id], rel)
}
}

return cli.Relations(dsToRels, stmt.Where)
default:
return unknownCoordinatorCommand
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/models/hashfunction/hashfunction.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,14 @@ func HashFunctionByName(hfn string) (HashFunctionType, error) {
return 0, errNoSuchHashFunction
}
}
func ToString(hf HashFunctionType) string {
switch hf {
case HashFunctionIdent:
return "identity"
case HashFunctionMurmur:
return "murmur"
case HashFunctionCity:
return "city"
}
return ""
}
49 changes: 43 additions & 6 deletions test/feature/features/memqdb.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ Feature: MemQDB save state into a file
"""
CREATE DISTRIBUTION ds1 COLUMN TYPES integer;
CREATE DISTRIBUTION ds2 COLUMN TYPES varchar;
ADD KEY RANGE krid1 FROM 1 TO 10 ROUTE TO sh1 FOR DISTRIBUTION ds1;
ADD KEY RANGE krid2 FROM 11 TO 20 ROUTE TO sh1 FOR DISTRIBUTION ds1;
ADD KEY RANGE krid3 FROM a ROUTE TO sh1 FOR DISTRIBUTION ds2;
ALTER DISTRIBUTION ds1 ATTACH RELATION a DISTRIBUTION KEY a_id;
ALTER DISTRIBUTION ds1 ATTACH RELATION b DISTRIBUTION KEY b_id;
ALTER DISTRIBUTION ds2 ATTACH RELATION c DISTRIBUTION KEY c_id;
"""
Then command return code should be "0"
When host "router" is stopped
Expand All @@ -39,6 +33,49 @@ Feature: MemQDB save state into a file
]
"""

Scenario: Attached relations restored
Given cluster environment is
"""
ROUTER_CONFIG=/spqr/test/feature/conf/router_with_backup.yaml
"""
Given cluster is up and running
When I execute SQL on host "router-admin"
"""
CREATE DISTRIBUTION ds1 COLUMN TYPES integer;
CREATE DISTRIBUTION ds2 COLUMN TYPES varchar;
ALTER DISTRIBUTION ds1 ATTACH RELATION a DISTRIBUTION KEY a_id HASH FUNCTION MURMUR;
ALTER DISTRIBUTION ds1 ATTACH RELATION b DISTRIBUTION KEY b_id;
ALTER DISTRIBUTION ds2 ATTACH RELATION c DISTRIBUTION KEY c_id;
"""
Then command return code should be "0"
When host "router" is stopped
And host "router" is started
When I run SQL on host "router-admin"
"""
SHOW relations;
"""
Then command return code should be "0"
And SQL result should match json_exactly
"""
[
{
"Relation name": "a",
"Distribution ID": "ds1",
"Distribution key": "(\"a_id\", murmur)"
},
{
"Relation name": "b",
"Distribution ID": "ds1",
"Distribution key": "(\"b_id\", identity)"
},
{
"Relation name": "c",
"Distribution ID": "ds2",
"Distribution key": "(\"c_id\", identity)"
}
]
"""

Scenario: Key ranges restored
Given cluster environment is
"""
Expand Down
1 change: 1 addition & 0 deletions test/regress/schedule/console
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ test: show_routers
test: show_key_ranges
test: show_distributions
test: show_version
test: show_relations
test: drop
test: add
test: hash
Expand Down
9 changes: 9 additions & 0 deletions test/regress/tests/console/expected/hash.out
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ SHOW DISTRIBUTIONS;
ds1 | integer
(1 row)

SHOW RELATIONS;
Relation name | Distribution ID | Distribution key
---------------+-----------------+--------------------
r1 | ds1 | ("col1", identity)
r2 | ds1 | ("col1", identity)
r3 | ds1 | ("col1", murmur)
r4 | ds1 | ("col1", city)
(4 rows)

DROP DISTRIBUTION ALL CASCADE;
drop distribution
-----------------------
Expand Down
67 changes: 67 additions & 0 deletions test/regress/tests/console/expected/show_relations.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

SQPR router admin console
Here you can configure your routing rules
------------------------------------------------
You can find documentation here
https://github.com/pg-sharding/spqr/tree/master/docs

CREATE DISTRIBUTION ds1 COLUMN TYPES integer;
add distribution
----------------------------------
created distribution with id ds1
(1 row)

CREATE DISTRIBUTION ds2 COLUMN TYPES varchar, integer;
add distribution
----------------------------------
created distribution with id ds2
(1 row)

ALTER DISTRIBUTION ds1 ATTACH RELATION a DISTRIBUTION KEY a_id;
attach table
-----------------------------------------
attached relation a to distribution ds1
(1 row)

ALTER DISTRIBUTION ds1 ATTACH RELATION b DISTRIBUTION KEY b_id HASH FUNCTION MURMUR;
attach table
-----------------------------------------
attached relation b to distribution ds1
(1 row)

ALTER DISTRIBUTION ds2 ATTACH RELATION c DISTRIBUTION KEY c_id_1 HASH FUNCTION IDENT,
c_id_2 HASH FUNCTION CITY;
attach table
-----------------------------------------
attached relation c to distribution ds2
(1 row)

SHOW relations;
Relation name | Distribution ID | Distribution key
---------------+-----------------+---------------------------------------
a | ds1 | ("a_id", identity)
b | ds1 | ("b_id", murmur)
c | ds2 | ("c_id_1", identity),("c_id_2", city)
(3 rows)

SHOW relations WHERE distribution_id = 'ds1';
Relation name | Distribution ID | Distribution key
---------------+-----------------+--------------------
a | ds1 | ("a_id", identity)
b | ds1 | ("b_id", murmur)
(2 rows)

SHOW relations WHERE unknown_param = 'ds1';
ERROR: column unknown_param does not exist.
DROP DISTRIBUTION ALL CASCADE;
drop distribution
-----------------------
drop distribution ds1
drop distribution ds2
(2 rows)

DROP KEY RANGE ALL;
drop key range
----------------
(0 rows)

1 change: 1 addition & 0 deletions test/regress/tests/console/sql/hash.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ALTER DISTRIBUTION ds1 ATTACH RELATION r3 DISTRIBUTION KEY col1 HASH FUNCTION MU
ALTER DISTRIBUTION ds1 ATTACH RELATION r4 DISTRIBUTION KEY col1 HASH FUNCTION CITY;

SHOW DISTRIBUTIONS;
SHOW RELATIONS;

DROP DISTRIBUTION ALL CASCADE;
DROP KEY RANGE ALL;
13 changes: 13 additions & 0 deletions test/regress/tests/console/sql/show_relations.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE DISTRIBUTION ds1 COLUMN TYPES integer;
CREATE DISTRIBUTION ds2 COLUMN TYPES varchar, integer;
ALTER DISTRIBUTION ds1 ATTACH RELATION a DISTRIBUTION KEY a_id;
ALTER DISTRIBUTION ds1 ATTACH RELATION b DISTRIBUTION KEY b_id HASH FUNCTION MURMUR;
ALTER DISTRIBUTION ds2 ATTACH RELATION c DISTRIBUTION KEY c_id_1 HASH FUNCTION IDENT,
c_id_2 HASH FUNCTION CITY;

SHOW relations;
SHOW relations WHERE distribution_id = 'ds1';
SHOW relations WHERE unknown_param = 'ds1';

DROP DISTRIBUTION ALL CASCADE;
DROP KEY RANGE ALL;
1 change: 1 addition & 0 deletions yacc/console/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ const (
BackendConnectionsStr = "backend_connections"
StatusStr = "status"
VersionStr = "version"
RelationsStr = "relations"
UnsupportedStr = "unsupported"
)

Expand Down
2 changes: 1 addition & 1 deletion yacc/console/gram.go

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

2 changes: 1 addition & 1 deletion yacc/console/gram.y
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ show_statement_type:
IDENT
{
switch v := strings.ToLower(string($1)); v {
case DatabasesStr, RoutersStr, PoolsStr, ShardsStr,BackendConnectionsStr, KeyRangesStr, ShardingRules, ClientsStr, StatusStr, DistributionsStr, VersionStr:
case DatabasesStr, RoutersStr, PoolsStr, ShardsStr, BackendConnectionsStr, KeyRangesStr, ShardingRules, ClientsStr, StatusStr, DistributionsStr, VersionStr, RelationsStr:
$$ = v
default:
$$ = UnsupportedStr
Expand Down
Loading

0 comments on commit 2ffa216

Please sign in to comment.