Skip to content

Commit 9361ada

Browse files
committed
Refactor and tune Explain table display
1 parent c4168b2 commit 9361ada

File tree

7 files changed

+61
-34
lines changed

7 files changed

+61
-34
lines changed

kvcmds/cmd_explain.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (c ExplainCmd) Handler() func(ctx context.Context) {
6262
}
6363
ret = append(ret, []string{planStr})
6464
}
65-
utils.PrintTable(ret)
65+
utils.PrintTableNoWrap(ret)
6666
return nil
6767
})
6868
}

query/filter_optimizer.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type ScanType struct {
2626
type FilterOptimizer struct {
2727
expr Expression
2828
filter *FilterExec
29-
txn *Txn
29+
txn Txn
3030
}
3131

3232
func (st *ScanType) String() string {
@@ -58,7 +58,7 @@ func ScanTypeToString(tp byte) string {
5858
return "UNKNOWN"
5959
}
6060

61-
func NewFilterOptimizer(ast *WhereStmt, t *Txn, filter *FilterExec) *FilterOptimizer {
61+
func NewFilterOptimizer(ast *WhereStmt, t Txn, filter *FilterExec) *FilterOptimizer {
6262
return &FilterOptimizer{
6363
expr: ast.Expr,
6464
txn: t,

query/kv.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package query
2+
3+
type Txn interface {
4+
Get(key []byte) (value []byte, err error)
5+
Cursor() (cursor Cursor, err error)
6+
}
7+
8+
type Cursor interface {
9+
Seek(prefix []byte) error
10+
Next() (key []byte, value []byte, err error)
11+
}

query/optimizer.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (o *Optimizer) init() error {
2525
return nil
2626
}
2727

28-
func (o *Optimizer) BuildPlan(t *Txn) (*ProjectionPlan, error) {
28+
func (o *Optimizer) BuildPlan(t Txn) (*ProjectionPlan, error) {
2929
err := o.init()
3030
if err != nil {
3131
return nil, err
@@ -71,7 +71,7 @@ func (o *Optimizer) BuildPlan(t *Txn) (*ProjectionPlan, error) {
7171
}, nil
7272
}
7373

74-
func (o *Optimizer) buildLimitPlan(t *Txn, fp Plan) Plan {
74+
func (o *Optimizer) buildLimitPlan(t Txn, fp Plan) Plan {
7575
return &LimitPlan{
7676
Txn: t,
7777
Start: o.stmt.Limit.Start,
@@ -80,7 +80,7 @@ func (o *Optimizer) buildLimitPlan(t *Txn, fp Plan) Plan {
8080
}
8181
}
8282

83-
func (o *Optimizer) buildOrderPlan(t *Txn, fp Plan) Plan {
83+
func (o *Optimizer) buildOrderPlan(t Txn, fp Plan) Plan {
8484
if len(o.stmt.Order.Orders) == 1 {
8585
order := o.stmt.Order.Orders[0]
8686
switch expr := order.Field.(type) {
@@ -98,7 +98,7 @@ func (o *Optimizer) buildOrderPlan(t *Txn, fp Plan) Plan {
9898
}
9999
}
100100

101-
func (o *Optimizer) buildScanPlan(t *Txn) Plan {
101+
func (o *Optimizer) buildScanPlan(t Txn) Plan {
102102
fopt := NewFilterOptimizer(o.filter.Ast, t, o.filter)
103103
return fopt.Optimize()
104104
}

query/plan.go

+16-16
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ var (
2929
type Column []byte
3030

3131
type FullScanPlan struct {
32-
Txn *Txn
32+
Txn Txn
3333
Filter *FilterExec
34-
iter *Cursor
34+
iter Cursor
3535
}
3636

37-
func NewFullScanPlan(t *Txn, f *FilterExec) Plan {
37+
func NewFullScanPlan(t Txn, f *FilterExec) Plan {
3838
return &FullScanPlan{
3939
Txn: t,
4040
Filter: f,
@@ -78,10 +78,10 @@ func (p *FullScanPlan) Next() ([]byte, []byte, error) {
7878
}
7979

8080
type EmptyResultPlan struct {
81-
Txn *Txn
81+
Txn Txn
8282
}
8383

84-
func NewEmptyResultPlan(t *Txn, f *FilterExec) Plan {
84+
func NewEmptyResultPlan(t Txn, f *FilterExec) Plan {
8585
return &EmptyResultPlan{
8686
Txn: t,
8787
}
@@ -104,13 +104,13 @@ func (p *EmptyResultPlan) Explain() []string {
104104
}
105105

106106
type PrefixScanPlan struct {
107-
Txn *Txn
107+
Txn Txn
108108
Filter *FilterExec
109109
Prefix string
110-
iter *Cursor
110+
iter Cursor
111111
}
112112

113-
func NewPrefixScanPlan(t *Txn, f *FilterExec, p string) Plan {
113+
func NewPrefixScanPlan(t Txn, f *FilterExec, p string) Plan {
114114
return &PrefixScanPlan{
115115
Txn: t,
116116
Filter: f,
@@ -163,14 +163,14 @@ func (p *PrefixScanPlan) Explain() []string {
163163
}
164164

165165
type MultiGetPlan struct {
166-
Txn *Txn
166+
Txn Txn
167167
Filter *FilterExec
168168
Keys []string
169169
numKeys int
170170
idx int
171171
}
172172

173-
func NewMultiGetPlan(t *Txn, f *FilterExec, keys []string) Plan {
173+
func NewMultiGetPlan(t Txn, f *FilterExec, keys []string) Plan {
174174
// We should sort keys to ensure order by erase works correctly
175175
sort.Strings(keys)
176176
return &MultiGetPlan{
@@ -222,7 +222,7 @@ func (p *MultiGetPlan) Explain() []string {
222222
}
223223

224224
type LimitPlan struct {
225-
Txn *Txn
225+
Txn Txn
226226
Start int
227227
Count int
228228
current int
@@ -276,7 +276,7 @@ func (p *LimitPlan) Explain() []string {
276276
}
277277

278278
type ProjectionPlan struct {
279-
Txn *Txn
279+
Txn Txn
280280
ChildPlan Plan
281281
AllFields bool
282282
Fields []Expression
@@ -502,7 +502,7 @@ func (h orderRowHeap) Less(i, j int) bool {
502502
}
503503

504504
type OrderPlan struct {
505-
Txn *Txn
505+
Txn Txn
506506
Orders []OrderField
507507
ChildPlan Plan
508508
pos int
@@ -577,14 +577,14 @@ func (p *OrderPlan) Explain() []string {
577577
}
578578

579579
type RangeScanPlan struct {
580-
Txn *Txn
580+
Txn Txn
581581
Filter *FilterExec
582582
Start []byte
583583
End []byte
584-
iter *Cursor
584+
iter Cursor
585585
}
586586

587-
func NewRangeScanPlan(t *Txn, f *FilterExec, start []byte, end []byte) Plan {
587+
func NewRangeScanPlan(t Txn, f *FilterExec, start []byte, end []byte) Plan {
588588
return &RangeScanPlan{
589589
Txn: t,
590590
Filter: f,

query/query_txn.go

+17-11
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,48 @@ import (
1010
"github.com/magiconair/properties"
1111
)
1212

13-
type Txn struct {
13+
var (
14+
_ Txn = (*queryTxn)(nil)
15+
_ Cursor = (*queryCursor)(nil)
16+
)
17+
18+
type queryTxn struct {
1419
client client.Client
1520
}
1621

17-
func NewQueryTxn(client client.Client) *Txn {
18-
return &Txn{
22+
func NewQueryTxn(client client.Client) Txn {
23+
return &queryTxn{
1924
client: client,
2025
}
2126
}
2227

23-
func (t *Txn) Get(key []byte) ([]byte, error) {
28+
func (t *queryTxn) Get(key []byte) ([]byte, error) {
2429
kv, err := t.client.Get(context.TODO(), client.Key(key))
2530
if err != nil {
2631
return nil, err
2732
}
2833
return kv.V, nil
2934
}
3035

31-
func (t *Txn) Cursor() (*Cursor, error) {
32-
return &Cursor{
36+
func (t *queryTxn) Cursor() (Cursor, error) {
37+
return &queryCursor{
3338
txn: t,
3439
batch: nil,
3540
prefix: []byte{},
3641
iterPos: 0,
3742
}, nil
3843
}
3944

40-
type Cursor struct {
41-
txn *Txn
45+
type queryCursor struct {
46+
txn *queryTxn
4247
batch client.KVS
4348
batchSize int
4449
prefix []byte
4550
iterPos int
4651
prevLastKey []byte
4752
}
4853

49-
func (c *Cursor) loadBatch() error {
54+
func (c *queryCursor) loadBatch() error {
5055
scanOpt := properties.NewProperties()
5156
scanOpt.Set(tcli.ScanOptLimit, "10")
5257
scanOpt.Set(tcli.ScanOptKeyOnly, "false")
@@ -61,6 +66,7 @@ func (c *Cursor) loadBatch() error {
6166
c.batchSize = n
6267
c.iterPos = 0
6368
if len(kvs) > 0 {
69+
// Skip first key
6470
if c.prevLastKey != nil && bytes.Compare(kvs[0].K, c.prevLastKey) == 0 {
6571
c.batch = c.batch[1:]
6672
c.batchSize--
@@ -71,7 +77,7 @@ func (c *Cursor) loadBatch() error {
7177
return nil
7278
}
7379

74-
func (c *Cursor) Next() (key []byte, val []byte, err error) {
80+
func (c *queryCursor) Next() (key []byte, val []byte, err error) {
7581
if c.batch == nil || c.iterPos >= c.batchSize {
7682
err = c.loadBatch()
7783
if err != nil {
@@ -88,7 +94,7 @@ func (c *Cursor) Next() (key []byte, val []byte, err error) {
8894
return key, val, nil
8995
}
9096

91-
func (c *Cursor) Seek(key []byte) error {
97+
func (c *queryCursor) Seek(key []byte) error {
9298
c.prefix = key
9399
c.batch = nil
94100
c.batchSize = 0

utils/utils.go

+10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ func PrintTable(data [][]string) {
3131
table.Render()
3232
}
3333

34+
func PrintTableNoWrap(data [][]string) {
35+
table := tablewriter.NewWriter(os.Stdout)
36+
table.SetHeader(data[0])
37+
table.SetAutoWrapText(false)
38+
table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
39+
table.SetCenterSeparator("|")
40+
table.AppendBulk(data[1:])
41+
table.Render()
42+
}
43+
3444
func OutputWithElapse(f func() error) error {
3545
tt := time.Now()
3646
err := f()

0 commit comments

Comments
 (0)