diff --git a/api.go b/api.go index 608961872..8650cd251 100644 --- a/api.go +++ b/api.go @@ -3339,6 +3339,7 @@ type SystemAPI interface { ClusterReplicaCount() int ShardWidth() int ClusterState() string + DataDir() string ClusterNodes() []ClusterNode } @@ -3407,6 +3408,10 @@ func (fsapi *FeatureBaseSystemAPI) ClusterState() string { return string(state) } +func (fsapi *FeatureBaseSystemAPI) DataDir() string { + return fsapi.server.dataDir +} + func (fsapi *FeatureBaseSystemAPI) ClusterNodes() []ClusterNode { result := make([]ClusterNode, 0) diff --git a/sql3/planner/compileshow.go b/sql3/planner/compileshow.go index 2952dc394..d55c0ba5a 100644 --- a/sql3/planner/compileshow.go +++ b/sql3/planner/compileshow.go @@ -70,7 +70,7 @@ func (p *ExecutionPlanner) compileShowTablesStatement(stmt parser.Statement) (ty dataType: parser.NewDataTypeString(), }} - return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseTables(pilosa.TablesToIndexInfos(tbls))), p.sql), nil + return NewPlanOpQuery(p, NewPlanOpProjection(columns, NewPlanOpFeatureBaseTables(p, pilosa.TablesToIndexInfos(tbls))), p.sql), nil } func (p *ExecutionPlanner) compileShowColumnsStatement(stmt *parser.ShowColumnsStatement) (_ types.PlanOperator, err error) { diff --git a/sql3/planner/opfeaturebasetables.go b/sql3/planner/opfeaturebasetables.go index 302039bb7..59b03375d 100644 --- a/sql3/planner/opfeaturebasetables.go +++ b/sql3/planner/opfeaturebasetables.go @@ -5,6 +5,7 @@ package planner import ( "context" "fmt" + "strings" "time" pilosa "github.com/featurebasedb/featurebase/v3" @@ -15,12 +16,14 @@ import ( // PlanOpFeatureBaseTables wraps a []*IndexInfo that is returned from // schemaAPI.Schema(). type PlanOpFeatureBaseTables struct { + planner *ExecutionPlanner indexInfo []*pilosa.IndexInfo warnings []string } -func NewPlanOpFeatureBaseTables(indexInfo []*pilosa.IndexInfo) *PlanOpFeatureBaseTables { +func NewPlanOpFeatureBaseTables(planner *ExecutionPlanner, indexInfo []*pilosa.IndexInfo) *PlanOpFeatureBaseTables { return &PlanOpFeatureBaseTables{ + planner: planner, indexInfo: indexInfo, warnings: make([]string, 0), } @@ -82,6 +85,11 @@ func (p *PlanOpFeatureBaseTables) Schema() types.Schema { ColumnName: "keys", Type: parser.NewDataTypeBool(), }, + &types.PlannerColumn{ + RelationName: "fb_tables", + ColumnName: "space_used", + Type: parser.NewDataTypeInt(), + }, &types.PlannerColumn{ RelationName: "fb_tables", ColumnName: "description", @@ -96,15 +104,17 @@ func (p *PlanOpFeatureBaseTables) Children() []types.PlanOperator { func (p *PlanOpFeatureBaseTables) Iterator(ctx context.Context, row types.Row) (types.RowIterator, error) { return &showTablesRowIter{ + planner: p.planner, indexInfo: p.indexInfo, }, nil } func (p *PlanOpFeatureBaseTables) WithChildren(children ...types.PlanOperator) (types.PlanOperator, error) { - return NewPlanOpFeatureBaseTables(p.indexInfo), nil + return NewPlanOpFeatureBaseTables(p.planner, p.indexInfo), nil } type showTablesRowIter struct { + planner *ExecutionPlanner indexInfo []*pilosa.IndexInfo rowIndex int } @@ -113,16 +123,37 @@ var _ types.RowIterator = (*showTablesRowIter)(nil) func (i *showTablesRowIter) Next(ctx context.Context) (types.Row, error) { if i.rowIndex < len(i.indexInfo) { + + indexName := i.indexInfo[i.rowIndex].Name + + var err error + var spaceUsed pilosa.DiskUsage + switch strings.ToLower(indexName) { + case "fb_cluster_info", "fb_cluster_nodes", "fb_performance_counters", "fb_exec_requests", "fb_table_ddl": + spaceUsed = pilosa.DiskUsage{ + Usage: 0, + } + default: + u := i.planner.systemAPI.DataDir() + u = fmt.Sprintf("%s/indexes/%s", u, indexName) + + spaceUsed, err = pilosa.GetDiskUsage(u) + if err != nil { + return nil, err + } + } + createdAt := time.Unix(0, i.indexInfo[i.rowIndex].CreatedAt) updatedAt := time.Unix(0, i.indexInfo[i.rowIndex].UpdatedAt) row := []interface{}{ - i.indexInfo[i.rowIndex].Name, - i.indexInfo[i.rowIndex].Name, + indexName, + indexName, i.indexInfo[i.rowIndex].Owner, i.indexInfo[i.rowIndex].LastUpdateUser, createdAt.Format(time.RFC3339), updatedAt.Format(time.RFC3339), i.indexInfo[i.rowIndex].Options.Keys, + spaceUsed.Usage, i.indexInfo[i.rowIndex].Options.Description, } i.rowIndex += 1 diff --git a/sql3/planner/opsystemtable.go b/sql3/planner/opsystemtable.go index a0fb33431..949b63bfe 100644 --- a/sql3/planner/opsystemtable.go +++ b/sql3/planner/opsystemtable.go @@ -103,6 +103,11 @@ var systemTables = map[string]*systemTable{ ColumnName: "is_primary", Type: parser.NewDataTypeBool(), }, + &types.PlannerColumn{ + RelationName: fbClusterNodes, + ColumnName: "space_used", + Type: parser.NewDataTypeBool(), + }, }, }, @@ -323,6 +328,12 @@ func (i *fbClusterNodesRowIter) Next(ctx context.Context) (types.Row, error) { i.result = i.planner.systemAPI.ClusterNodes() } + u := i.planner.systemAPI.DataDir() + spaceUsed, err := pilosa.GetDiskUsage(u) + if err != nil { + return nil, err + } + if len(i.result) > 0 { n := i.result[0] row := []interface{}{ @@ -331,6 +342,7 @@ func (i *fbClusterNodesRowIter) Next(ctx context.Context) (types.Row, error) { n.URI, n.GRPCURI, n.IsPrimary, + spaceUsed.Usage, } // Move to next result element. i.result = i.result[1:] diff --git a/sql3/sql_complex_test.go b/sql3/sql_complex_test.go index dc1f9effb..c038bfc72 100644 --- a/sql3/sql_complex_test.go +++ b/sql3/sql_complex_test.go @@ -102,6 +102,7 @@ func TestPlanner_Show(t *testing.T) { wireQueryFieldString("uri"), wireQueryFieldString("grpc_uri"), wireQueryFieldBool("is_primary"), + wireQueryFieldBool("space_used"), }, columns); diff != "" { t.Fatal(diff) }