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

Fix dolt_statistics table for multiple schemas for doltgres #8589

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
github.com/dolthub/fslock v0.0.3
github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81
github.com/dolthub/vitess v0.0.0-20241126205153-88972ec5fe52
github.com/dolthub/vitess v0.0.0-20241126223332-cd8f828f26ac
github.com/dustin/go-humanize v1.0.1
github.com/fatih/color v1.13.0
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568
Expand Down Expand Up @@ -57,7 +57,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0
github.com/creasty/defaults v1.6.0
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
github.com/dolthub/go-mysql-server v0.18.2-0.20241126213642-de3d54a398ac
github.com/dolthub/go-mysql-server v0.18.2-0.20241127000145-a1809677932e
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63
github.com/dolthub/swiss v0.1.0
github.com/goccy/go-json v0.10.2
Expand Down
8 changes: 4 additions & 4 deletions go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U=
github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0=
github.com/dolthub/go-icu-regex v0.0.0-20240916130659-0118adc6b662 h1:aC17hZD6iwzBwwfO5M+3oBT5E5gGRiQPdn+vzpDXqIA=
github.com/dolthub/go-icu-regex v0.0.0-20240916130659-0118adc6b662/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168=
github.com/dolthub/go-mysql-server v0.18.2-0.20241126213642-de3d54a398ac h1:tit+TpLRkR918++5HAFLvbfBQklUsn7+XCYJOCZCZ+Q=
github.com/dolthub/go-mysql-server v0.18.2-0.20241126213642-de3d54a398ac/go.mod h1:grCMUuyP/ZaQh8JDhr/AdFc/+fc9h71uislzsV4k3UM=
github.com/dolthub/go-mysql-server v0.18.2-0.20241127000145-a1809677932e h1:2oysRPgywCpyW/h4m6DxYUpUsdZ+JkJXvC51TVr4sUE=
github.com/dolthub/go-mysql-server v0.18.2-0.20241127000145-a1809677932e/go.mod h1:QdaXQKE8XFwM4P1yN14m2eydx4V2xyuqpQp4tmNoXzQ=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q=
github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718 h1:lT7hE5k+0nkBdj/1UOSFwjWpNxf+LCApbRHgnCA17XE=
Expand All @@ -197,8 +197,8 @@ github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9X
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81/go.mod h1:siLfyv2c92W1eN/R4QqG/+RjjX5W2+gCTRjZxBjI3TY=
github.com/dolthub/swiss v0.1.0 h1:EaGQct3AqeP/MjASHLiH6i4TAmgbG/c4rA6a1bzCOPc=
github.com/dolthub/swiss v0.1.0/go.mod h1:BeucyB08Vb1G9tumVN3Vp/pyY4AMUnr9p7Rz7wJ7kAQ=
github.com/dolthub/vitess v0.0.0-20241126205153-88972ec5fe52 h1:RH0eygj4DLPQ6fvJCBBk4ZOq3PpeIQU/1ot6Fye9WCU=
github.com/dolthub/vitess v0.0.0-20241126205153-88972ec5fe52/go.mod h1:alcJgfdyIhFaAiYyEmuDCFSLCzedz3KCaIclLoCUtJg=
github.com/dolthub/vitess v0.0.0-20241126223332-cd8f828f26ac h1:A0U/OdIqdCkAV0by7MVBbnSyZBsa94ZjIZxx7PhjBW4=
github.com/dolthub/vitess v0.0.0-20241126223332-cd8f828f26ac/go.mod h1:alcJgfdyIhFaAiYyEmuDCFSLCzedz3KCaIclLoCUtJg=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
Expand Down
30 changes: 28 additions & 2 deletions go/libraries/doltcore/sqle/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,26 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds
}
}
case doltdb.StatisticsTableName:
dt, found = dtables.NewStatisticsTable(ctx, db.Name(), db.ddb, asOf), true
if resolve.UseSearchPath && db.schemaName == "" {
schemaName, err := resolve.FirstExistingSchemaOnSearchPath(ctx, root)
if err != nil {
return nil, false, err
}
db.schemaName = schemaName
}

var tables []string
var err error
branch, ok := asOf.(string)
if ok && branch != "" {
tables, err = db.GetTableNamesAsOf(ctx, branch)
} else {
tables, err = db.GetTableNames(ctx)
}
if err != nil {
return nil, false, err
}
dt, found = dtables.NewStatisticsTable(ctx, db.Name(), db.schemaName, branch, tables), true
case doltdb.ProceduresTableName:
found = true
backingTable, _, err := db.getTable(ctx, root, doltdb.ProceduresTableName)
Expand Down Expand Up @@ -856,7 +875,14 @@ func (db Database) GetTableNamesAsOf(ctx *sql.Context, time interface{}) ([]stri
return nil, nil
}

tblNames, err := db.getAllTableNames(ctx, root, false)
showSystemTablesVar, err := ctx.GetSessionVariable(ctx, dsess.ShowSystemTables)
if err != nil {
return nil, err
}

showSystemTables := showSystemTablesVar.(int8) == 1

tblNames, err := db.getAllTableNames(ctx, root, showSystemTables)
if err != nil {
return nil, err
}
Expand Down
57 changes: 11 additions & 46 deletions go/libraries/doltcore/sqle/dtables/statistics_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
package dtables

import (
"fmt"

"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/stats"

Expand All @@ -28,21 +26,18 @@ import (

// StatisticsTable is a sql.Table implementation that implements a system table which shows the dolt commit log
type StatisticsTable struct {
dbName string
branch string
ddb *doltdb.DoltDB
dbName string
schemaName string
branch string
tableNames []string
}

var _ sql.Table = (*StatisticsTable)(nil)
var _ sql.StatisticsTable = (*StatisticsTable)(nil)

// NewStatisticsTable creates a StatisticsTable
func NewStatisticsTable(_ *sql.Context, dbName string, ddb *doltdb.DoltDB, asOf interface{}) sql.Table {
ret := &StatisticsTable{dbName: dbName, ddb: ddb}
if branch, ok := asOf.(string); ok {
ret.branch = branch
}
return ret
func NewStatisticsTable(_ *sql.Context, dbName, schemaName, branch string, tableNames []string) sql.Table {
return &StatisticsTable{dbName: dbName, schemaName: schemaName, branch: branch, tableNames: tableNames}
}

// DataLength implements sql.StatisticsTable
Expand Down Expand Up @@ -73,28 +68,16 @@ func (st *StatisticsTable) DataLength(ctx *sql.Context) (uint64, error) {
}

type BranchStatsProvider interface {
GetTableDoltStats(ctx *sql.Context, branch, db, table string) ([]sql.Statistic, error)
GetTableDoltStats(ctx *sql.Context, branch, db, schema, table string) ([]sql.Statistic, error)
}

// RowCount implements sql.StatisticsTable
func (st *StatisticsTable) RowCount(ctx *sql.Context) (uint64, bool, error) {
dSess := dsess.DSessFromSess(ctx.Session)
prov := dSess.Provider()

sqlDb, err := prov.Database(ctx, st.dbName)
if err != nil {
return 0, false, err
}

tables, err := sqlDb.GetTableNames(ctx)
if err != nil {
return 0, false, err
}

var cnt int
for _, table := range tables {
for _, table := range st.tableNames {
// only Dolt-specific provider has branch support
dbStats, err := dSess.StatsProvider().(BranchStatsProvider).GetTableDoltStats(ctx, st.branch, st.dbName, table)
dbStats, err := dSess.StatsProvider().(BranchStatsProvider).GetTableDoltStats(ctx, st.branch, st.dbName, st.schemaName, table)
if err != nil {

}
Expand Down Expand Up @@ -136,28 +119,10 @@ func (st *StatisticsTable) Partitions(*sql.Context) (sql.PartitionIter, error) {
// PartitionRows is a sql.Table interface function that gets a row iterator for a partition
func (st *StatisticsTable) PartitionRows(ctx *sql.Context, _ sql.Partition) (sql.RowIter, error) {
dSess := dsess.DSessFromSess(ctx.Session)
prov := dSess.Provider()

var sqlDb sql.Database
var err error
if st.branch != "" {
sqlDb, err = prov.Database(ctx, fmt.Sprintf("%s/%s", st.dbName, st.branch))
} else {
sqlDb, err = prov.Database(ctx, st.dbName)
}
if err != nil {
return nil, err
}

tables, err := sqlDb.GetTableNames(ctx)
if err != nil {
return nil, err
}

statsPro := dSess.StatsProvider().(BranchStatsProvider)
var dStats []sql.Statistic
for _, table := range tables {
dbStats, err := statsPro.GetTableDoltStats(ctx, st.branch, st.dbName, table)
for _, table := range st.tableNames {
dbStats, err := statsPro.GetTableDoltStats(ctx, st.branch, st.dbName, st.schemaName, table)
if err != nil {
return nil, err
}
Expand Down
16 changes: 9 additions & 7 deletions go/libraries/doltcore/sqle/statsnoms/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (

var ErrIncompatibleVersion = errors.New("client stats version mismatch")

func NewStatsIter(ctx *sql.Context, m prolly.Map) (*statsIter, error) {
func NewStatsIter(ctx *sql.Context, schemaName string, m prolly.Map) (*statsIter, error) {
iter, err := m.IterAll(ctx)
if err != nil {
return nil, err
Expand All @@ -43,11 +43,12 @@ func NewStatsIter(ctx *sql.Context, m prolly.Map) (*statsIter, error) {
ns := m.NodeStore()

return &statsIter{
iter: iter,
kb: keyBuilder,
vb: valueBuilder,
ns: ns,
planb: planbuilder.New(ctx, nil, nil, nil),
iter: iter,
kb: keyBuilder,
vb: valueBuilder,
ns: ns,
schemaName: schemaName,
planb: planbuilder.New(ctx, nil, nil, nil),
}, nil
}

Expand All @@ -61,6 +62,7 @@ type statsIter struct {
ns tree.NodeStore
planb *planbuilder.Builder
currentQual string
schemaName string
currentTypes []sql.Type
}

Expand Down Expand Up @@ -118,7 +120,7 @@ func (s *statsIter) Next(ctx *sql.Context) (sql.Row, error) {
typs[i] = strings.TrimSpace(t)
}

qual := sql.NewStatQualifier(dbName, tableName, indexName)
qual := sql.NewStatQualifier(dbName, s.schemaName, tableName, indexName)
if curQual := qual.String(); !strings.EqualFold(curQual, s.currentQual) {
s.currentQual = curQual
s.currentTypes, err = parseTypeStrings(typs)
Expand Down
5 changes: 3 additions & 2 deletions go/libraries/doltcore/sqle/statsnoms/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ import (

func loadStats(ctx *sql.Context, db dsess.SqlDatabase, m prolly.Map) (map[sql.StatQualifier]*statspro.DoltStats, error) {
qualToStats := make(map[sql.StatQualifier]*statspro.DoltStats)
iter, err := NewStatsIter(ctx, m)
schemaName := db.SchemaName()
iter, err := NewStatsIter(ctx, schemaName, m)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -72,7 +73,7 @@ func loadStats(ctx *sql.Context, db dsess.SqlDatabase, m prolly.Map) (map[sql.St
typs[i] = strings.TrimSpace(t)
}

qual := sql.NewStatQualifier(dbName, tableName, indexName)
qual := sql.NewStatQualifier(dbName, schemaName, tableName, indexName)
if currentStat.Statistic.Qual.String() != qual.String() {
if !currentStat.Statistic.Qual.Empty() {
currentStat.Statistic.LowerBnd, currentStat.Tb, err = loadLowerBound(ctx, db, currentStat.Statistic.Qual, len(currentStat.Columns()))
Expand Down
8 changes: 6 additions & 2 deletions go/libraries/doltcore/sqle/statspro/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ func (p *Provider) RefreshTableStatsWithBranch(ctx *sql.Context, table sql.Table

tableName := strings.ToLower(table.Name())
dbName := strings.ToLower(db)
var schemaName string
if schTab, ok := table.(sql.DatabaseSchemaTable); ok {
schemaName = strings.ToLower(schTab.DatabaseSchema().SchemaName())
}

iat, ok := table.(sql.IndexAddressableTable)
if !ok {
Expand Down Expand Up @@ -146,7 +150,7 @@ func (p *Provider) RefreshTableStatsWithBranch(ctx *sql.Context, table sql.Table
ctx.GetLogger().Debugf("statistics refresh: detected table schema change: %s,%s/%s", dbName, table, branch)
statDb.SetSchemaHash(branch, tableName, schHash)

stats, err := p.GetTableDoltStats(ctx, branch, dbName, tableName)
stats, err := p.GetTableDoltStats(ctx, branch, dbName, schemaName, tableName)
if err != nil {
return err
}
Expand All @@ -163,7 +167,7 @@ func (p *Provider) RefreshTableStatsWithBranch(ctx *sql.Context, table sql.Table
cols[i] = strings.TrimPrefix(strings.ToLower(c), tablePrefix)
}

qual := sql.NewStatQualifier(db, table.Name(), strings.ToLower(idx.ID()))
qual := sql.NewStatQualifier(db, schemaName, table.Name(), strings.ToLower(idx.ID()))
curStat, ok := statDb.GetStat(branch, qual)
if !ok {
curStat = NewDoltStats()
Expand Down
9 changes: 7 additions & 2 deletions go/libraries/doltcore/sqle/statspro/auto_refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,18 @@ func (p *Provider) checkRefresh(ctx *sql.Context, sqlDb sql.Database, dbName, br
return err
}

var schemaName string
if schTab, ok := sqlTable.(sql.DatabaseSchemaTable); ok {
schemaName = strings.ToLower(schTab.DatabaseSchema().SchemaName())
}

if oldSchHash := statDb.GetSchemaHash(branch, table); oldSchHash.IsEmpty() {
statDb.SetSchemaHash(branch, table, schHash)
} else if oldSchHash != schHash {
ctx.GetLogger().Debugf("statistics refresh: detected table schema change: %s,%s/%s", dbName, table, branch)
statDb.SetSchemaHash(branch, table, schHash)

stats, err := p.GetTableDoltStats(ctx, branch, dbName, table)
stats, err := p.GetTableDoltStats(ctx, branch, dbName, schemaName, table)
if err != nil {
return err
}
Expand All @@ -191,7 +196,7 @@ func (p *Provider) checkRefresh(ctx *sql.Context, sqlDb sql.Database, dbName, br
// collect indexes and ranges to be updated
var idxMetas []indexMeta
for _, index := range indexes {
qual := sql.NewStatQualifier(dbName, table, strings.ToLower(index.ID()))
qual := sql.NewStatQualifier(dbName, schemaName, table, strings.ToLower(index.ID()))
qualExists[qual] = true
curStat, ok := statDb.GetStat(branch, qual)
if !ok {
Expand Down
30 changes: 21 additions & 9 deletions go/libraries/doltcore/sqle/statspro/stats_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,15 @@ func (p *Provider) GetTableStats(ctx *sql.Context, db string, table sql.Table) (
return nil, nil
}

// TODO: schema name
return p.GetTableDoltStats(ctx, branch, db, table.Name())
var schemaName string
if schTab, ok := table.(sql.DatabaseSchemaTable); ok {
schemaName = strings.ToLower(schTab.DatabaseSchema().SchemaName())
}

return p.GetTableDoltStats(ctx, branch, db, schemaName, table.Name())
}

func (p *Provider) GetTableDoltStats(ctx *sql.Context, branch, db, table string) ([]sql.Statistic, error) {
func (p *Provider) GetTableDoltStats(ctx *sql.Context, branch, db, schema, table string) ([]sql.Statistic, error) {
statDb, ok := p.getStatDb(db)
if !ok || statDb == nil {
return nil, nil
Expand All @@ -190,7 +194,7 @@ func (p *Provider) GetTableDoltStats(ctx *sql.Context, branch, db, table string)

var ret []sql.Statistic
for _, qual := range statDb.ListStatQuals(branch) {
if strings.EqualFold(db, qual.Database) && strings.EqualFold(table, qual.Tab) {
if strings.EqualFold(db, qual.Database) && strings.EqualFold(schema, qual.Sch) && strings.EqualFold(table, qual.Tab) {
stat, _ := statDb.GetStat(branch, qual)
ret = append(ret, stat)
}
Expand Down Expand Up @@ -333,8 +337,12 @@ func (p *Provider) RowCount(ctx *sql.Context, db string, table sql.Table) (uint6
return 0, err
}

// TODO: schema name
priStats, ok := statDb.GetStat(branch, sql.NewStatQualifier(db, table.Name(), "primary"))
var schemaName string
if schTab, ok := table.(sql.DatabaseSchemaTable); ok {
schemaName = strings.ToLower(schTab.DatabaseSchema().SchemaName())
}

priStats, ok := statDb.GetStat(branch, sql.NewStatQualifier(db, schemaName, table.Name(), "primary"))
if !ok {
return 0, nil
}
Expand All @@ -354,8 +362,12 @@ func (p *Provider) DataLength(ctx *sql.Context, db string, table sql.Table) (uin
return 0, err
}

// TODO: schema name
priStats, ok := statDb.GetStat(branch, sql.NewStatQualifier(db, table.Name(), "primary"))
var schemaName string
if schTab, ok := table.(sql.DatabaseSchemaTable); ok {
schemaName = strings.ToLower(schTab.DatabaseSchema().SchemaName())
}

priStats, ok := statDb.GetStat(branch, sql.NewStatQualifier(db, schemaName, table.Name(), "primary"))
if !ok {
return 0, nil
}
Expand Down Expand Up @@ -404,7 +416,7 @@ func (p *Provider) Prune(ctx *sql.Context) error {
}
defer p.UnlockTable(branch, dbName, t)

tableStats, err := p.GetTableDoltStats(ctx, branch, dbName, t)
tableStats, err := p.GetTableDoltStats(ctx, branch, dbName, sqlDb.SchemaName(), t)
if err != nil {
return err
}
Expand Down
Loading