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 ORDER BY selecting for clients #744

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/auth/krb5.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import (
"encoding/hex"
"fmt"
"log"

"github.com/jackc/pgx/v5/pgproto3"
"github.com/jcmturner/gokrb5/v8/credentials"
"github.com/jcmturner/gokrb5/v8/gssapi"
"github.com/jcmturner/gokrb5/v8/keytab"
"github.com/jcmturner/gokrb5/v8/service"
"github.com/pg-sharding/spqr/pkg/client"
"log"
)

type BaseAuthModule struct {
Expand Down Expand Up @@ -91,12 +92,12 @@
if status.Code != gssapi.StatusComplete && status.Code != gssapi.StatusContinueNeeded {
errText := fmt.Sprintf("Kerberos validation error: %v", status)
log.Print(errText)
return nil, fmt.Errorf(errText)

Check failure on line 95 in pkg/auth/krb5.go

View workflow job for this annotation

GitHub Actions / golangci-lint

printf: non-constant format string in call to fmt.Errorf (govet)
}
if status.Code == gssapi.StatusContinueNeeded {
errText := "Kerberos GSS-API continue needed"
log.Print(errText)
return nil, fmt.Errorf(errText)
return nil, fmt.Errorf("%s", errText)
}
if authed {
ctx := st.Context()
Expand All @@ -105,6 +106,6 @@
} else {
errText := "Kerberos authentication failed"
log.Print(errText)
return nil, fmt.Errorf(errText)

Check failure on line 109 in pkg/auth/krb5.go

View workflow job for this annotation

GitHub Actions / golangci-lint

printf: non-constant format string in call to fmt.Errorf (govet)
}
}
62 changes: 50 additions & 12 deletions pkg/clientinteractor/interactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,16 +720,17 @@ func GetColumnsMap(desc TableDesc) map[string]int {
//
// Returns:
// - error: An error if any occurred during the operation.
func (pi *PSQLInteractor) Clients(ctx context.Context, clients []client.ClientInfo, condition spqrparser.WhereClauseNode) error {
func (pi *PSQLInteractor) Clients(ctx context.Context, clients []client.ClientInfo, query *spqrparser.Show) error {
desc := ClientDesc{}
header := desc.GetHeader()
rowDesc := GetColumnsMap(desc)

condition := query.Where
order := query.Order
if err := pi.WriteHeader(header...); err != nil {
spqrlog.Zero.Error().Err(err).Msg("")
return err
}

var data [][]string
for _, cl := range clients {
if len(cl.Shards()) > 0 {
for _, sh := range cl.Shards() {
Expand All @@ -745,11 +746,7 @@ func (pi *PSQLInteractor) Clients(ctx context.Context, clients []client.ClientIn
if !match {
continue
}

if err := pi.WriteDataRow(row...); err != nil {
spqrlog.Zero.Error().Err(err).Msg("")
return err
}
data = append(data, row)
}
} else {
row := desc.GetRow(cl, "no backend connection", cl.RAddr())
Expand All @@ -762,17 +759,58 @@ func (pi *PSQLInteractor) Clients(ctx context.Context, clients []client.ClientIn
continue
}

if err := pi.WriteDataRow(row...); err != nil {
spqrlog.Zero.Error().Err(err).Msg("")
return err
}
data = append(data, row)
}

}
switch order.(type) {
case spqrparser.Order:
ord := order.(spqrparser.Order)
var asc_desc int

switch ord.OptAscDesc.(type) {
case spqrparser.SortByAsc:
asc_desc = ASC
case spqrparser.SortByDesc:
asc_desc = DESC
case spqrparser.SortByDefault:
asc_desc = ASC
default:
return fmt.Errorf("wrong sorting option (asc/desc)")
}
sortable := SortableWithContext{data, rowDesc[ord.Col.ColName], asc_desc}
sort.Sort(sortable)
}
for i := 0; i < len(data); i++ {
if err := pi.WriteDataRow(data[i]...); err != nil {
spqrlog.Zero.Error().Err(err).Msg("")
return err
}
}
return pi.CompleteMsg(len(clients))
}

const (
ASC = iota
DESC
)

type SortableWithContext struct {
Data [][]string
Col_index int
Order int
}

func (a SortableWithContext) Len() int { return len(a.Data) }
func (a SortableWithContext) Swap(i, j int) { a.Data[i], a.Data[j] = a.Data[j], a.Data[i] }
func (a SortableWithContext) Less(i, j int) bool {
if a.Order == ASC {
return a.Data[i][a.Col_index] < a.Data[j][a.Col_index]
} else {
return a.Data[i][a.Col_index] > a.Data[j][a.Col_index]
}
}

// TODO : unit tests

// Distributions sends distribution data to the PSQL client.
Expand Down
12 changes: 11 additions & 1 deletion pkg/clientinteractor/interactor_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package clientinteractor_test

import (
"sort"
"testing"

"github.com/golang/mock/gomock"
mock "github.com/pg-sharding/spqr/pkg/mock/clientinteractor"
"testing"

"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -175,3 +177,11 @@ func TestGetColumnsMap(t *testing.T) {
}

}

func TestSortableWithContext(t *testing.T) {
data := [][]string{[]string{"a", "b"}, []string{"b", "a"}}
rev_data := [][]string{[]string{"b", "a"}, []string{"a", "b"}}
sortable := clientinteractor.SortableWithContext{data, 0, clientinteractor.DESC}
sort.Sort(sortable)
assert.Equal(t, data, rev_data)
}
2 changes: 1 addition & 1 deletion pkg/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ func ProcessShow(ctx context.Context, stmt *spqrparser.Show, mngr EntityMgr, ci
return err
}

return cli.Clients(ctx, resp, stmt.Where)
return cli.Clients(ctx, resp, stmt)
case spqrparser.PoolsStr:
var respPools []pool.Pool
if err := ci.ForEachPool(func(p pool.Pool) error {
Expand Down
4 changes: 2 additions & 2 deletions pkg/models/spqrerror/spqrerror.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ type SpqrError struct {
// - *SpqrError: The created SpqrError.
func New(errorCode string, errorMsg string) *SpqrError {
err := &SpqrError{
Err: fmt.Errorf(errorMsg),
Err: fmt.Errorf("%s", errorMsg),
ErrorCode: errorCode,
}
return err
Expand All @@ -95,7 +95,7 @@ func New(errorCode string, errorMsg string) *SpqrError {
// - *SpqrError: The created SpqrError.
func NewByCode(errorCode string) *SpqrError {
err := &SpqrError{
Err: fmt.Errorf(GetMessageByCode(errorCode)),
Err: fmt.Errorf("%s", GetMessageByCode(errorCode)),
ErrorCode: errorCode,
}
return err
Expand Down
3 changes: 2 additions & 1 deletion router/statistics/query_time_statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ var queryStatistics = statistics{

func InitStatistics(q []float64) {
queryStatistics.Quantiles = q
if queryStatistics.Quantiles != nil && len(queryStatistics.Quantiles) > 0 {

if len(queryStatistics.Quantiles) > 0 { // also not nil
queryStatistics.NeedToCollectData = false
} else {
queryStatistics.NeedToCollectData = true
Expand Down
19 changes: 19 additions & 0 deletions yacc/console/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ type ColumnRef struct {
TableAlias string
ColName string
}
type OptAscDesc interface{}

type SortByDefault struct {
OptAscDesc
}
type SortByAsc struct {
OptAscDesc
}
type SortByDesc struct {
OptAscDesc
}
type OrderClause interface{}

type Order struct {
OrderClause
OptAscDesc OptAscDesc
Col ColumnRef
}

type WhereClauseNode interface {
}
Expand Down Expand Up @@ -31,6 +49,7 @@ type WhereClauseOp struct {
type Show struct {
Cmd string
Where WhereClauseNode
Order OrderClause
}

type Set struct {
Expand Down
Loading
Loading