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

Add 'SHOW realtions' method to console #515

Merged
merged 13 commits into from
Feb 26, 2024
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
Denchick marked this conversation as resolved.
Show resolved Hide resolved
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;
EinKrebs marked this conversation as resolved.
Show resolved Hide resolved
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
Loading