From 65fcda27ad0dfc4b1fd60b8fe40339b082fd94d2 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 28 Apr 2023 16:17:39 -0700 Subject: [PATCH 001/167] Note-taking and cleanup --- .../sqle/dsess/database_session_state.go | 17 +++++++++++++++-- go/libraries/doltcore/sqle/dsess/session.go | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index bcb9a680d5..490d8a6b43 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -38,7 +38,6 @@ type InitialDbState struct { HeadRoot *doltdb.RootValue ReadOnly bool DbData env.DbData - ReadReplica *env.Remote Remotes map[string]env.Remote Branches map[string]env.BranchConfig Backups map[string]env.Remote @@ -57,20 +56,34 @@ type SessionDatabase interface { InitialDBState(ctx *sql.Context, branch string) (InitialDbState, error) } +// DatabaseSessionState is the set of all information for a given database in this session. type DatabaseSessionState struct { + // dbName is the name of the database this state applies to. This includes a revision specifier in some cases. dbName string + // db is the database this state applies to db SqlDatabase + // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which + // case headRoot must be set. headCommit *doltdb.Commit + // HeadRoot is the root value for databases without a headCommit. Nil for databases with a headCommit. headRoot *doltdb.RootValue + // WorkingSet is the working set for this database. May be nil for databases tied to a detached root value, in which + // case headCommit must be set WorkingSet *doltdb.WorkingSet + // dbData is an accessor for the underlying doltDb dbData env.DbData + // WriteSession is this database's write session, which changes when the working set changes WriteSession writer.WriteSession + // globalState is the global state of this session (shared by all sessions for a particular db) globalState globalstate.GlobalState + // readOnly is true if this database is read only readOnly bool + // dirty is true if this session has uncommitted changes dirty bool - readReplica *env.Remote + // tmpFileDir is the directory to use for temporary files for this database tmpFileDir string + // sessionCache is a collection of cached values used to speed up performance sessionCache *SessionCache // Same as InitialDbState.Err, this signifies that this diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 52ac0d16ef..f7da57004f 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1164,7 +1164,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { adapter := NewSessionStateAdapter(d, db.Name(), dbState.Remotes, dbState.Branches, dbState.Backups) sessionState.dbData.Rsr = adapter sessionState.dbData.Rsw = adapter - sessionState.readOnly, sessionState.readReplica = dbState.ReadOnly, dbState.ReadReplica + sessionState.readOnly = dbState.ReadOnly // TODO: figure out how to cast this to dsqle.SqlDatabase without creating import cycles // Or better yet, get rid of EditOptions from the database, it's a session setting @@ -1206,7 +1206,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { sessionState.headRoot = dbState.HeadRoot } - // This has to happen after SetRoot above, since it does a stale check before its work + // This has to happen after SetWorkingSet above, since it does a stale check before its work // TODO: this needs to be kept up to date as the working set ref changes sessionState.headCommit = dbState.HeadCommit From ed076afacf3f6b6b62715f370e31166e012736c3 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 28 Apr 2023 16:49:51 -0700 Subject: [PATCH 002/167] Beginning to encapsulate db state behind getters --- go/libraries/doltcore/sqle/database.go | 2 +- .../sqle/dsess/database_session_state.go | 31 ++++++++++++-- go/libraries/doltcore/sqle/dsess/session.go | 42 +++++++++---------- .../doltcore/sqle/dtables/ignore_table.go | 4 +- go/libraries/doltcore/sqle/tables.go | 2 +- go/libraries/doltcore/sqle/temp_table.go | 4 +- 6 files changed, 55 insertions(+), 30 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index a1ea508977..962d4af7bb 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -654,7 +654,7 @@ func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) { if !ok { return nil, fmt.Errorf("no root value found in session") } - return dbState.WorkingSet, nil + return dbState.GetWorkingSet(), nil } // SetRoot should typically be called on the Session, which is where this state lives. But it's available here as a diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 490d8a6b43..c8cf5c69d3 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -92,6 +92,31 @@ type DatabaseSessionState struct { Err error } +func (d *DatabaseSessionState) GetWorkingSet() *doltdb.WorkingSet { + // TODO: key off the current branch + return d.WorkingSet +} + +func (d *DatabaseSessionState) GetWriteSession() writer.WriteSession { + return d.WriteSession +} + +type dbData struct { + // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which + // case headRoot must be set. + headCommit *doltdb.Commit + // HeadRoot is the root value for databases without a headCommit. Nil for databases with a headCommit. + headRoot *doltdb.RootValue + // WorkingSet is the working set for this database. May be nil for databases tied to a detached root value, in which + // case headCommit must be set + WorkingSet *doltdb.WorkingSet + // dbData is an accessor for the underlying doltDb + dbData env.DbData + // WriteSession is this database's write session, which changes when the working set changes + WriteSession writer.WriteSession + // globalState is the global state of this session (shared by all sessions for a particular db) +} + func NewEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ sessionCache: newSessionCache(), @@ -99,7 +124,7 @@ func NewEmptyDatabaseSessionState() *DatabaseSessionState { } func (d DatabaseSessionState) GetRoots() doltdb.Roots { - if d.WorkingSet == nil { + if d.GetWorkingSet() == nil { return doltdb.Roots{ Head: d.headRoot, Working: d.headRoot, @@ -108,8 +133,8 @@ func (d DatabaseSessionState) GetRoots() doltdb.Roots { } return doltdb.Roots{ Head: d.headRoot, - Working: d.WorkingSet.WorkingRoot(), - Staged: d.WorkingSet.StagedRoot(), + Working: d.GetWorkingSet().WorkingRoot(), + Staged: d.GetWorkingSet().StagedRoot(), } } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index f7da57004f..1ab46192c6 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -230,10 +230,10 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { if !ok { return nil } - if sessionState.WorkingSet == nil { + if sessionState.GetWorkingSet() == nil { return nil } - wsRef := sessionState.WorkingSet.Ref() + wsRef := sessionState.GetWorkingSet().Ref() _, err = sessionState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) if err == doltdb.ErrWorkingSetNotFound { _, err = d.newWorkingSetForHead(ctx, wsRef, dbName) @@ -276,7 +276,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // There are both valid and invalid ways that a working set for the session state can be nil (e.g. connected to a // commit hash revision DB, or the DB contents cannot be loaded). Either way this transaction is defunct. // TODO: with multi-db transactions, such DBs should be ignored - if sessionState.WorkingSet == nil { + if sessionState.GetWorkingSet() == nil { return DisabledTransaction{}, nil } @@ -320,7 +320,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - wsRef := sessionState.WorkingSet.Ref() + wsRef := sessionState.GetWorkingSet().Ref() ws, err := sessionState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) // TODO: every HEAD needs a working set created when it is. We can get rid of this in a 1.0 release when this is fixed if err == doltdb.ErrWorkingSetNotFound { @@ -530,7 +530,7 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti return nil, fmt.Errorf("expected a DoltTransaction") } - mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, dbState.WorkingSet) + mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, dbState.GetWorkingSet()) if err != nil { return nil, err } @@ -573,8 +573,8 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do headHash, _ := headCommit.HashOf() var mergeParentCommits []*doltdb.Commit - if sessionState.WorkingSet.MergeActive() { - mergeParentCommits = []*doltdb.Commit{sessionState.WorkingSet.MergeState().Commit()} + if sessionState.GetWorkingSet().MergeActive() { + mergeParentCommits = []*doltdb.Commit{sessionState.GetWorkingSet().MergeState().Commit()} } else if props.Amend { numParentsHeadForAmend := headCommit.NumParents() for i := 0; i < numParentsHeadForAmend; i++ { @@ -592,7 +592,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do return nil, err } - err = d.SetWorkingSet(ctx, dbName, sessionState.WorkingSet.WithStagedRoot(newRoots.Staged)) + err = d.SetWorkingSet(ctx, dbName, sessionState.GetWorkingSet().WithStagedRoot(newRoots.Staged)) if err != nil { return nil, err } @@ -600,7 +600,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do roots.Head = newRoots.Head } - pendingCommit, err := actions.GetCommitStaged(ctx, roots, sessionState.WorkingSet, mergeParentCommits, sessionState.dbData.Ddb, props) + pendingCommit, err := actions.GetCommitStaged(ctx, roots, sessionState.GetWorkingSet(), mergeParentCommits, sessionState.dbData.Ddb, props) if err != nil { if props.Amend { _, err = actions.ResetSoftToRef(ctx, sessionState.dbData, headHash.String()) @@ -845,9 +845,9 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R // TODO: Return an error here? return nil } - sessionState.WorkingSet = sessionState.WorkingSet.WithWorkingRoot(newRoot) + sessionState.WorkingSet = sessionState.GetWorkingSet().WithWorkingRoot(newRoot) - return d.SetWorkingSet(ctx, dbName, sessionState.WorkingSet) + return d.SetWorkingSet(ctx, dbName, sessionState.GetWorkingSet()) } // SetRoots sets new roots for the session for the database named. Typically clients should only set the working root, @@ -860,7 +860,7 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo return err } - workingSet := sessionState.WorkingSet.WithWorkingRoot(roots.Working).WithStagedRoot(roots.Staged) + workingSet := sessionState.GetWorkingSet().WithWorkingRoot(roots.Working).WithStagedRoot(roots.Staged) return d.SetWorkingSet(ctx, dbName, workingSet) } @@ -875,7 +875,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. if err != nil { return err } - if ws.Ref() != sessionState.WorkingSet.Ref() { + if ws.Ref() != sessionState.GetWorkingSet().Ref() { return fmt.Errorf("must switch working sets with SwitchWorkingSet") } sessionState.WorkingSet = ws @@ -1029,7 +1029,7 @@ func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.Worki if err != nil { return nil, err } - return sessionState.WorkingSet, nil + return sessionState.GetWorkingSet(), nil } // GetHeadCommit returns the parent commit of the current session. @@ -1191,7 +1191,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if err != nil { return err } - sessionState.WriteSession = writer.NewWriteSession(nbf, sessionState.WorkingSet, tracker, editOpts) + sessionState.WriteSession = writer.NewWriteSession(nbf, sessionState.GetWorkingSet(), tracker, editOpts) if err = d.SetWorkingSet(ctx, db.Name(), dbState.WorkingSet); err != nil { return err } @@ -1255,11 +1255,11 @@ func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef, return nil, err } - if dbState.WorkingSet == nil { + if dbState.GetWorkingSet() == nil { return nil, nil } - return dbState.WorkingSet.Ref().ToHeadRef() + return dbState.GetWorkingSet().Ref().ToHeadRef() } func (d *DoltSession) Username() string { @@ -1283,8 +1283,8 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string) error // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here - if state.WorkingSet != nil { - headRef, err := state.WorkingSet.Ref().ToHeadRef() + if state.GetWorkingSet() != nil { + headRef, err := state.GetWorkingSet().Ref().ToHeadRef() if err != nil { return err } @@ -1425,8 +1425,8 @@ func (d *DoltSession) GetBranch() (string, error) { return "", err } - if dbState.WorkingSet != nil { - branchRef, err := dbState.WorkingSet.Ref().ToHeadRef() + if dbState.GetWorkingSet() != nil { + branchRef, err := dbState.GetWorkingSet().Ref().ToHeadRef() if err != nil { return "", err } diff --git a/go/libraries/doltcore/sqle/dtables/ignore_table.go b/go/libraries/doltcore/sqle/dtables/ignore_table.go index b0b3c71691..d779564f24 100644 --- a/go/libraries/doltcore/sqle/dtables/ignore_table.go +++ b/go/libraries/doltcore/sqle/dtables/ignore_table.go @@ -179,7 +179,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { iw.prevHash = &prevHash - iw.workingSet = dbState.WorkingSet + iw.workingSet = dbState.GetWorkingSet() found, err := roots.Working.HasTable(ctx, doltdb.IgnoreTableName) if err != nil { @@ -232,7 +232,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { // We use WriteSession.SetWorkingSet instead of DoltSession.SetRoot because we want to avoid modifying the root // until the end of the transaction, but we still want the WriteSession to be able to find the newly // created table. - err = dbState.WriteSession.SetWorkingSet(ctx, dbState.WorkingSet.WithWorkingRoot(newRootValue)) + err = dbState.WriteSession.SetWorkingSet(ctx, dbState.GetWorkingSet().WithWorkingRoot(newRootValue)) if err != nil { iw.errDuringStatementBegin = err return diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 5e30e68a2d..7ba4323b05 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -1257,7 +1257,7 @@ func (t *AlterableDoltTable) RewriteInserter( return nil, fmt.Errorf("database %s not found in session", t.db.Name()) } - ws := dbState.WorkingSet + ws := dbState.GetWorkingSet() head, err := sess.GetHeadCommit(ctx, t.db.Name()) if err != nil { diff --git a/go/libraries/doltcore/sqle/temp_table.go b/go/libraries/doltcore/sqle/temp_table.go index 7af1383840..3e52a6c2fa 100644 --- a/go/libraries/doltcore/sqle/temp_table.go +++ b/go/libraries/doltcore/sqle/temp_table.go @@ -78,7 +78,7 @@ func NewTempTable( return nil, fmt.Errorf("database %s not found in session", db) } - ws := dbState.WorkingSet + ws := dbState.GetWorkingSet() sch, err := temporaryDoltSchema(ctx, pkSch, collation) if err != nil { @@ -152,7 +152,7 @@ func setTempTableRoot(t *TempTable) func(ctx *sql.Context, dbName string, newRoo return fmt.Errorf("database %s not found in session", t.dbName) } - ws := dbState.WorkingSet + ws := dbState.GetWorkingSet() newWs := ws.WithWorkingRoot(newRoot) ait, err := globalstate.NewAutoIncrementTracker(ctx, newWs) From cf170cb0f37ba60b9b617106387437b9fb588b1d Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 28 Apr 2023 16:53:02 -0700 Subject: [PATCH 003/167] Moving write session behind a getter --- go/libraries/doltcore/sqle/database.go | 2 +- .../sqle/dprocedures/dolt_conflicts_resolve.go | 2 +- .../sqle/dsess/database_session_state.go | 4 ++-- go/libraries/doltcore/sqle/dsess/session.go | 18 +++++++++--------- .../doltcore/sqle/dtables/ignore_table.go | 4 ++-- go/libraries/doltcore/sqle/tables.go | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 962d4af7bb..50a1e672c2 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -1010,7 +1010,7 @@ func (db Database) Flush(ctx *sql.Context) error { if err != nil { return err } - editSession := dbState.WriteSession + editSession := dbState.GetWriteSession() ws, err := editSession.Flush(ctx) if err != nil { diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go b/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go index e26aa829f0..bdca65346b 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go @@ -419,7 +419,7 @@ func ResolveDataConflicts(ctx *sql.Context, dSess *dsess.DoltSession, root *dolt if err != nil { return err } - opts := state.WriteSession.GetOptions() + opts := state.GetWriteSession().GetOptions() tbl, err = resolveNomsConflicts(ctx, opts, tbl, tblName, sch) } if err != nil { diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index c8cf5c69d3..b6d3dbc471 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -98,7 +98,7 @@ func (d *DatabaseSessionState) GetWorkingSet() *doltdb.WorkingSet { } func (d *DatabaseSessionState) GetWriteSession() writer.WriteSession { - return d.WriteSession + return d.GetWriteSession() } type dbData struct { @@ -143,5 +143,5 @@ func (d *DatabaseSessionState) SessionCache() *SessionCache { } func (d DatabaseSessionState) EditOpts() editor.Options { - return d.WriteSession.GetOptions() + return d.GetWriteSession().GetOptions() } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 1ab46192c6..07d860becb 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -199,7 +199,7 @@ func (d *DoltSession) Flush(ctx *sql.Context, dbName string) error { return err } - ws, err := dbState.WriteSession.Flush(ctx) + ws, err := dbState.GetWriteSession().Flush(ctx) if err != nil { return err } @@ -340,7 +340,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // SetWorkingSet always sets the dirty bit, but by definition we are clean at transaction start sessionState.dirty = false - return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, sessionState.dbData, sessionState.WriteSession.GetOptions(), tCharacteristic), nil + return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, sessionState.dbData, sessionState.GetWriteSession().GetOptions(), tCharacteristic), nil } // clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, @@ -907,7 +907,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return err } - err = sessionState.WriteSession.SetWorkingSet(ctx, ws) + err = sessionState.GetWriteSession().SetWorkingSet(ctx, ws) if err != nil { return err } @@ -993,7 +993,7 @@ func (d *DoltSession) SwitchWorkingSet( } // make a fresh WriteSession, discard existing WriteSession - opts := sessionState.WriteSession.GetOptions() + opts := sessionState.GetWriteSession().GetOptions() nbf := ws.WorkingRoot().VRW().Format() tracker, err := sessionState.globalState.GetAutoIncrementTracker(ctx) if err != nil { @@ -1017,7 +1017,7 @@ func (d *DoltSession) SwitchWorkingSet( ws, wsRef, sessionState.dbData, - sessionState.WriteSession.GetOptions(), + sessionState.GetWriteSession().GetOptions(), tCharacteristic, )) @@ -1099,15 +1099,15 @@ func (d *DoltSession) setForeignKeyChecksSessionVar(ctx *sql.Context, key string } if intVal == 0 { for _, dbState := range d.dbStates { - opts := dbState.WriteSession.GetOptions() + opts := dbState.GetWriteSession().GetOptions() opts.ForeignKeyChecksDisabled = true - dbState.WriteSession.SetOptions(opts) + dbState.GetWriteSession().SetOptions(opts) } } else if intVal == 1 { for _, dbState := range d.dbStates { - opts := dbState.WriteSession.GetOptions() + opts := dbState.GetWriteSession().GetOptions() opts.ForeignKeyChecksDisabled = false - dbState.WriteSession.SetOptions(opts) + dbState.GetWriteSession().SetOptions(opts) } } else { return fmt.Errorf("variable 'foreign_key_checks' can't be set to the value of '%d'", intVal) diff --git a/go/libraries/doltcore/sqle/dtables/ignore_table.go b/go/libraries/doltcore/sqle/dtables/ignore_table.go index d779564f24..39fc783d8b 100644 --- a/go/libraries/doltcore/sqle/dtables/ignore_table.go +++ b/go/libraries/doltcore/sqle/dtables/ignore_table.go @@ -232,7 +232,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { // We use WriteSession.SetWorkingSet instead of DoltSession.SetRoot because we want to avoid modifying the root // until the end of the transaction, but we still want the WriteSession to be able to find the newly // created table. - err = dbState.WriteSession.SetWorkingSet(ctx, dbState.GetWorkingSet().WithWorkingRoot(newRootValue)) + err = dbState.GetWriteSession().SetWorkingSet(ctx, dbState.GetWorkingSet().WithWorkingRoot(newRootValue)) if err != nil { iw.errDuringStatementBegin = err return @@ -241,7 +241,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { dSess.SetRoot(ctx, dbName, newRootValue) } - tableWriter, err := dbState.WriteSession.GetTableWriter(ctx, doltdb.IgnoreTableName, dbName, dSess.SetRoot, false) + tableWriter, err := dbState.GetWriteSession().GetTableWriter(ctx, doltdb.IgnoreTableName, dbName, dSess.SetRoot, false) if err != nil { iw.errDuringStatementBegin = err return diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 7ba4323b05..10173bb1d3 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -526,7 +526,7 @@ func (t *WritableDoltTable) getTableEditor(ctx *sql.Context) (ed writer.TableWri } setter := ds.SetRoot - ed, err = state.WriteSession.GetTableWriter(ctx, t.tableName, t.db.Name(), setter, batched) + ed, err = state.GetWriteSession().GetTableWriter(ctx, t.tableName, t.db.Name(), setter, batched) if err != nil { return nil, err @@ -1363,7 +1363,7 @@ func (t *AlterableDoltTable) RewriteInserter( // We can't just call getTableEditor here because it uses the session state, which we can't update until after the // rewrite operation - opts := dbState.WriteSession.GetOptions() + opts := dbState.GetWriteSession().GetOptions() opts.ForeignKeyChecksDisabled = true newRoot, err := ws.WorkingRoot().PutTable(ctx, t.Name(), dt) From c29fd94a4f787b06227cd1734c38df5eae80bebd Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 1 May 2023 15:45:42 -0700 Subject: [PATCH 004/167] Always return a revision DB from provider.Database() --- .../doltcore/sqle/database_provider.go | 39 +++++++++++++------ go/libraries/doltcore/sqle/dsess/session.go | 6 +++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 43bde6f25c..2074254aca 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1041,23 +1041,25 @@ func resolveAncestorSpec(ctx *sql.Context, revSpec string, ddb *doltdb.DoltDB) ( // SessionDatabase implements dsess.SessionDatabaseProvider func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (dsess.SqlDatabase, bool, error) { + baseName := name + isRevisionDb := strings.Contains(name, dsess.DbRevisionDelimiter) + + if isRevisionDb { + // TODO: formalize and enforce this rule (can't allow DBs with / in the name) + // TODO: some connectors will take issue with the /, we need other mechanisms to support them + parts := strings.SplitN(name, dsess.DbRevisionDelimiter, 2) + baseName = parts[0] + } + var ok bool p.mu.RLock() - db, ok := p.databases[formatDbMapKeyName(name)] + db, ok := p.databases[strings.ToLower(baseName)] standby := *p.isStandby p.mu.RUnlock() - if ok { - return wrapForStandby(db, standby), true, nil - } - - // Revision databases aren't tracked in the map, just instantiated on demand - db, ok, err := p.databaseForRevision(ctx, name) - if err != nil { - return nil, false, err - } - - // A final check: if the database doesn't exist and this is a read replica, attempt to clone it from the remote + + // If the database doesn't exist and this is a read replica, attempt to clone it from the remote if !ok { + var err error db, err = p.databaseForClone(ctx, name) if err != nil { @@ -1069,6 +1071,18 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds } } + // The db map only contains base databases, not revision DBs. Convert to a revision DB for creation. + if !isRevisionDb { + // TODO: capture the initial checked out head at startup, don't get it here every time + headRef := db.DbData().Rsr.CWBHeadRef() + name = baseName + dsess.DbRevisionDelimiter + headRef.GetPath() + } + + db, ok, err := p.databaseForRevision(ctx, name) + if err != nil { + return nil, false, err + } + return wrapForStandby(db, standby), true, nil } @@ -1446,6 +1460,7 @@ func (s staticRepoState) CWBHeadRef() ref.DoltRef { // formatDbMapKeyName returns formatted string of database name and/or branch name. Database name is case-insensitive, // so it's stored in lower case name. Branch name is case-sensitive, so not changed. +// TODO: branch names should be case-insensitive too func formatDbMapKeyName(name string) string { if !strings.Contains(name, dsess.DbRevisionDelimiter) { return strings.ToLower(name) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 07d860becb..1578fac029 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -170,6 +170,12 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*DatabaseS return dbState, true, nil } +// TODO NEXT: the lookupdbstate method is the key abstraction point. It proxies all non-revisoined DBs to a revisioned +// state, based on the current db (the default branch if none). The session stores all data by working set ref. DB +// names are masked on return in the case of a non-revisined DB. Session stae is also responsible for keeping track of +// the checked out branch in the case of a default (no branch-specified) db connection. +// Alternate idea: branch head is always set correctly in response to a USE statement, OR a checkout procedure. The +// latter implicitly updates the current database. You also get a revision db checked out on connection to no branch. func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (*DatabaseSessionState, bool, error) { s, ok, err := d.lookupDbState(ctx, dbName) if err != nil { From abf91974ac80a743f37e13e10ad3a585840e3384 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 1 May 2023 16:14:11 -0700 Subject: [PATCH 005/167] Pulled out new interface --- .../sqle/dsess/database_session_state.go | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index b6d3dbc471..0f7682e6a6 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -15,6 +15,7 @@ package dsess import ( + "github.com/dolthub/dolt/go/libraries/doltcore/ref" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" @@ -62,22 +63,12 @@ type DatabaseSessionState struct { dbName string // db is the database this state applies to db SqlDatabase - // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which - // case headRoot must be set. - headCommit *doltdb.Commit - // HeadRoot is the root value for databases without a headCommit. Nil for databases with a headCommit. - headRoot *doltdb.RootValue - // WorkingSet is the working set for this database. May be nil for databases tied to a detached root value, in which - // case headCommit must be set - WorkingSet *doltdb.WorkingSet - // dbData is an accessor for the underlying doltDb - dbData env.DbData - // WriteSession is this database's write session, which changes when the working set changes - WriteSession writer.WriteSession + // currentHead is the current head of the database when unqualified by a DB name + currentHead ref.WorkingSetRef + // heads records the in-memory DB state for every branch head accessed by the session + heads map[ref.WorkingSetRef]dbData // globalState is the global state of this session (shared by all sessions for a particular db) globalState globalstate.GlobalState - // readOnly is true if this database is read only - readOnly bool // dirty is true if this session has uncommitted changes dirty bool // tmpFileDir is the directory to use for temporary files for this database @@ -92,13 +83,18 @@ type DatabaseSessionState struct { Err error } -func (d *DatabaseSessionState) GetWorkingSet() *doltdb.WorkingSet { - // TODO: key off the current branch - return d.WorkingSet +type SessionState interface { + GetWorkingSet() *doltdb.WorkingSet + GetWriteSession() writer.WriteSession } -func (d *DatabaseSessionState) GetWriteSession() writer.WriteSession { - return d.GetWriteSession() + +func (d *dbData) GetWorkingSet() *doltdb.WorkingSet { + return d.workingSet +} + +func (d *dbData) GetWriteSession() writer.WriteSession { + return d.writeSession } type dbData struct { @@ -107,14 +103,16 @@ type dbData struct { headCommit *doltdb.Commit // HeadRoot is the root value for databases without a headCommit. Nil for databases with a headCommit. headRoot *doltdb.RootValue - // WorkingSet is the working set for this database. May be nil for databases tied to a detached root value, in which + // workingSet is the working set for this database. May be nil for databases tied to a detached root value, in which // case headCommit must be set - WorkingSet *doltdb.WorkingSet + workingSet *doltdb.WorkingSet // dbData is an accessor for the underlying doltDb dbData env.DbData - // WriteSession is this database's write session, which changes when the working set changes - WriteSession writer.WriteSession + // writeSession is this database's write session, which changes when the working set changes + writeSession writer.WriteSession // globalState is the global state of this session (shared by all sessions for a particular db) + // readOnly is true if this database is read only + readOnly bool } func NewEmptyDatabaseSessionState() *DatabaseSessionState { @@ -124,7 +122,7 @@ func NewEmptyDatabaseSessionState() *DatabaseSessionState { } func (d DatabaseSessionState) GetRoots() doltdb.Roots { - if d.GetWorkingSet() == nil { + if d.GetWorkingSet(ctx) == nil { return doltdb.Roots{ Head: d.headRoot, Working: d.headRoot, @@ -133,8 +131,8 @@ func (d DatabaseSessionState) GetRoots() doltdb.Roots { } return doltdb.Roots{ Head: d.headRoot, - Working: d.GetWorkingSet().WorkingRoot(), - Staged: d.GetWorkingSet().StagedRoot(), + Working: d.GetWorkingSet(ctx).WorkingRoot(), + Staged: d.GetWorkingSet(ctx).StagedRoot(), } } From 6ffe5ac3c98e6c35d9078ade220280250585fdc5 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 1 May 2023 16:54:48 -0700 Subject: [PATCH 006/167] AddDb --- .../sqle/dsess/database_session_state.go | 12 ++- go/libraries/doltcore/sqle/dsess/session.go | 93 +++++++++++-------- 2 files changed, 59 insertions(+), 46 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 0f7682e6a6..bf9d0c16db 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -66,7 +66,7 @@ type DatabaseSessionState struct { // currentHead is the current head of the database when unqualified by a DB name currentHead ref.WorkingSetRef // heads records the in-memory DB state for every branch head accessed by the session - heads map[ref.WorkingSetRef]dbData + heads map[string]*branchState // globalState is the global state of this session (shared by all sessions for a particular db) globalState globalstate.GlobalState // dirty is true if this session has uncommitted changes @@ -88,16 +88,16 @@ type SessionState interface { GetWriteSession() writer.WriteSession } - -func (d *dbData) GetWorkingSet() *doltdb.WorkingSet { +func (d *branchState) GetWorkingSet() *doltdb.WorkingSet { return d.workingSet } -func (d *dbData) GetWriteSession() writer.WriteSession { +func (d *branchState) GetWriteSession() writer.WriteSession { return d.writeSession } -type dbData struct { +// branchState records all the in-memory session state for a particular branch head +type branchState struct { // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which // case headRoot must be set. headCommit *doltdb.Commit @@ -118,6 +118,8 @@ type dbData struct { func NewEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ sessionCache: newSessionCache(), + heads: make(map[ref.WorkingSetRef]branchState), + // TODO: current head? } } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 1578fac029..aa1b508ec5 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -135,17 +135,27 @@ func DSessFromSess(sess sql.Session) *DoltSession { } // LookupDbState returns the session state for the database named -func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*DatabaseSessionState, bool, error) { +func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (branchState, bool, error) { + // TODO: change to require a db, not a name + dbName = strings.ToLower(dbName) d.mu.Lock() dbState, ok := d.dbStates[dbName] d.mu.Unlock() + + if !ok { + return branchState{}, false, nil + } + if ok { + if dbState.Err != nil { + return branchState{}, false, dbState.Err + } + + // TODO: fill in return dbState, ok, nil } - // TODO: this needs to include the transaction's snapshot of the DB at tx start time - database, ok, err := d.provider.SessionDatabase(ctx, dbName) if err != nil { return nil, false, err @@ -176,14 +186,11 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*DatabaseS // the checked out branch in the case of a default (no branch-specified) db connection. // Alternate idea: branch head is always set correctly in response to a USE statement, OR a checkout procedure. The // latter implicitly updates the current database. You also get a revision db checked out on connection to no branch. -func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (*DatabaseSessionState, bool, error) { +func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (SessionState, bool, error) { s, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, false, err } - if ok && s.Err != nil { - return nil, false, s.Err - } return s, ok, nil } @@ -1135,55 +1142,58 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { DefineSystemVariablesForDB(db.Name()) - sessionState := NewEmptyDatabaseSessionState() - d.mu.Lock() - d.dbStates[strings.ToLower(db.Name())] = sessionState - d.mu.Unlock() - sessionState.dbName = db.Name() - sessionState.db = db - - _, val, ok := sql.SystemVariables.GetGlobal(DefaultBranchKey(db.Name())) - initialBranch := "" - if ok { - initialBranch = val.(string) - } - - // TODO: the branch should be already set if the DB was specified with a branch revision string - dbState, err := db.InitialDBState(ctx, initialBranch) + var sessionState *DatabaseSessionState + branchState := &branchState{} + baseName, rev := SplitRevisionDbName(db) + + dbState, err := db.InitialDBState(ctx, rev) if err != nil { return err } + d.mu.Lock() + if _, ok := d.dbStates[strings.ToLower(baseName)]; !ok { + sessionState = NewEmptyDatabaseSessionState() + d.dbStates[strings.ToLower(baseName)] = sessionState + sessionState.heads[strings.ToLower(rev)] = branchState + + tmpDir, err := dbState.DbData.Rsw.TempTableFilesDir() + if err != nil { + if errors.Is(err, env.ErrDoltRepositoryNotFound) { + return env.ErrFailedToAccessDB.New(dbState.Db.Name()) + } + return err + } + sessionState.tmpFileDir = tmpDir + } + d.mu.Unlock() + + sessionState.dbName = baseName + // TODO: this doesn't seem right, shouldn't be a revision DB + sessionState.db = db + // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and // the writer with one that errors out // TODO: this no longer gets called at session creation time, so the error handling below never occurs when a // database is deleted out from under a running server - sessionState.dbData = dbState.DbData - tmpDir, err := dbState.DbData.Rsw.TempTableFilesDir() - if err != nil { - if errors.Is(err, env.ErrDoltRepositoryNotFound) { - return env.ErrFailedToAccessDB.New(dbState.Db.Name()) - } - return err - } - sessionState.tmpFileDir = tmpDir + branchState.dbData = dbState.DbData adapter := NewSessionStateAdapter(d, db.Name(), dbState.Remotes, dbState.Branches, dbState.Backups) - sessionState.dbData.Rsr = adapter - sessionState.dbData.Rsw = adapter - sessionState.readOnly = dbState.ReadOnly + branchState.dbData.Rsr = adapter + branchState.dbData.Rsw = adapter + branchState.readOnly = dbState.ReadOnly // TODO: figure out how to cast this to dsqle.SqlDatabase without creating import cycles // Or better yet, get rid of EditOptions from the database, it's a session setting nbf := types.Format_Default - if sessionState.dbData.Ddb != nil { - nbf = sessionState.dbData.Ddb.Format() + if branchState.dbData.Ddb != nil { + nbf = branchState.dbData.Ddb.Format() } editOpts := db.(interface{ EditOptions() editor.Options }).EditOptions() if dbState.Err != nil { sessionState.Err = dbState.Err } else if dbState.WorkingSet != nil { - sessionState.WorkingSet = dbState.WorkingSet + branchState.workingSet = dbState.WorkingSet // TODO: this is pretty clunky, there is a silly dependency between InitialDbState and globalstate.StateProvider // that's hard to express with the current types @@ -1197,7 +1207,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if err != nil { return err } - sessionState.WriteSession = writer.NewWriteSession(nbf, sessionState.GetWorkingSet(), tracker, editOpts) + branchState.writeSession = writer.NewWriteSession(nbf, branchState.GetWorkingSet(), tracker, editOpts) if err = d.SetWorkingSet(ctx, db.Name(), dbState.WorkingSet); err != nil { return err } @@ -1207,16 +1217,17 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if err != nil { return err } - sessionState.headRoot = headRoot + branchState.headRoot = headRoot } else if dbState.HeadRoot != nil { - sessionState.headRoot = dbState.HeadRoot + branchState.headRoot = dbState.HeadRoot } // This has to happen after SetWorkingSet above, since it does a stale check before its work // TODO: this needs to be kept up to date as the working set ref changes - sessionState.headCommit = dbState.HeadCommit + branchState.headCommit = dbState.HeadCommit // After setting the initial root we have no state to commit + // TODO: do we still want to track dirty states, or just look at hashes sessionState.dirty = false if sessionState.Err == nil { From 47f184f45d8bec723765c3e4be7b1f48bb1feba1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 1 May 2023 17:20:19 -0700 Subject: [PATCH 007/167] Use BranchState everywhere in session.go --- .../sqle/dsess/database_session_state.go | 37 ++-- go/libraries/doltcore/sqle/dsess/session.go | 168 ++++++++++-------- 2 files changed, 112 insertions(+), 93 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index bf9d0c16db..04144fffa1 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -83,6 +83,20 @@ type DatabaseSessionState struct { Err error } +func NewEmptyDatabaseSessionState() *DatabaseSessionState { + return &DatabaseSessionState{ + sessionCache: newSessionCache(), + heads: make(map[string]*branchState), + // TODO: current head? + } +} + +func (d *DatabaseSessionState) SessionCache() *SessionCache { + return d.sessionCache +} + +// SessionState is the public interface for dealing with session state outside this package. Session-state is always +// branch-specific. type SessionState interface { GetWorkingSet() *doltdb.WorkingSet GetWriteSession() writer.WriteSession @@ -98,6 +112,7 @@ func (d *branchState) GetWriteSession() writer.WriteSession { // branchState records all the in-memory session state for a particular branch head type branchState struct { + dbState *DatabaseSessionState // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which // case headRoot must be set. headCommit *doltdb.Commit @@ -115,16 +130,8 @@ type branchState struct { readOnly bool } -func NewEmptyDatabaseSessionState() *DatabaseSessionState { - return &DatabaseSessionState{ - sessionCache: newSessionCache(), - heads: make(map[ref.WorkingSetRef]branchState), - // TODO: current head? - } -} - -func (d DatabaseSessionState) GetRoots() doltdb.Roots { - if d.GetWorkingSet(ctx) == nil { +func (d branchState) GetRoots() doltdb.Roots { + if d.GetWorkingSet() == nil { return doltdb.Roots{ Head: d.headRoot, Working: d.headRoot, @@ -133,15 +140,11 @@ func (d DatabaseSessionState) GetRoots() doltdb.Roots { } return doltdb.Roots{ Head: d.headRoot, - Working: d.GetWorkingSet(ctx).WorkingRoot(), - Staged: d.GetWorkingSet(ctx).StagedRoot(), + Working: d.GetWorkingSet().WorkingRoot(), + Staged: d.GetWorkingSet().StagedRoot(), } } -func (d *DatabaseSessionState) SessionCache() *SessionCache { - return d.sessionCache -} - -func (d DatabaseSessionState) EditOpts() editor.Options { +func (d branchState) EditOpts() editor.Options { return d.GetWriteSession().GetOptions() } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index aa1b508ec5..1570590292 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -135,8 +135,8 @@ func DSessFromSess(sess sql.Session) *DoltSession { } // LookupDbState returns the session state for the database named -func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (branchState, bool, error) { - // TODO: change to require a db, not a name +func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchState, bool, error) { + // TODO: change to require a db, not a name? dbName = strings.ToLower(dbName) d.mu.Lock() @@ -144,16 +144,19 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (branchStat d.mu.Unlock() if !ok { - return branchState{}, false, nil + return nil, false, nil } + + _, rev := SplitRevisionDbName(dbState.db) + branchState, ok := dbState.heads[strings.ToLower(rev)] if ok { if dbState.Err != nil { - return branchState{}, false, dbState.Err + return nil, false, dbState.Err } // TODO: fill in - return dbState, ok, nil + return branchState, ok, nil } database, ok, err := d.provider.SessionDatabase(ctx, dbName) @@ -177,7 +180,9 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (branchStat return nil, false, sql.ErrDatabaseNotFound.New(dbName) } - return dbState, true, nil + branchState = dbState.heads[strings.ToLower(rev)] + + return branchState, true, nil } // TODO NEXT: the lookupdbstate method is the key abstraction point. It proxies all non-revisoined DBs to a revisioned @@ -236,7 +241,7 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { if d.validateErr != nil { return d.validateErr } - sessionState, ok, err := d.LookupDbState(ctx, dbName) + sessionState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return err } @@ -275,9 +280,10 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } // New transaction, clear all session state + // TODO: revisit this d.clearRevisionDbState() - sessionState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } @@ -289,13 +295,13 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // There are both valid and invalid ways that a working set for the session state can be nil (e.g. connected to a // commit hash revision DB, or the DB contents cannot be loaded). Either way this transaction is defunct. // TODO: with multi-db transactions, such DBs should be ignored - if sessionState.GetWorkingSet() == nil { + if branchState.GetWorkingSet() == nil { return DisabledTransaction{}, nil } // TODO: this needs to happen for every DB in the database, not just the one named in the transaction - if sessionState != nil && sessionState.db != nil { - rrd, ok := sessionState.db.(RemoteReadReplicaDatabase) + if branchState != nil && branchState.dbState.db != nil { + rrd, ok := branchState.dbState.db.(RemoteReadReplicaDatabase) if ok && rrd.ValidReplicaState(ctx) { err := rrd.PullFromRemote(ctx) if err != nil && !IgnoreReplicationErrors() { @@ -306,7 +312,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - if sessionState.readOnly { + if branchState.readOnly { return DisabledTransaction{}, nil } @@ -325,7 +331,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } if _, v, ok := sql.SystemVariables.GetGlobal(ReadReplicaRemote); ok && v != "" { - err = sessionState.dbData.Ddb.Rebase(ctx) + err = branchState.dbData.Ddb.Rebase(ctx) if err != nil && !IgnoreReplicationErrors() { return nil, err } else if err != nil { @@ -333,8 +339,8 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - wsRef := sessionState.GetWorkingSet().Ref() - ws, err := sessionState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) + wsRef := branchState.GetWorkingSet().Ref() + ws, err := branchState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) // TODO: every HEAD needs a working set created when it is. We can get rid of this in a 1.0 release when this is fixed if err == doltdb.ErrWorkingSetNotFound { ws, err = d.newWorkingSetForHead(ctx, wsRef, dbName) @@ -351,9 +357,9 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra err = d.SetWorkingSet(ctx, dbName, ws) // SetWorkingSet always sets the dirty bit, but by definition we are clean at transaction start - sessionState.dirty = false + branchState.dbState.dirty = false - return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, sessionState.dbData, sessionState.GetWriteSession().GetOptions(), tCharacteristic), nil + return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, branchState.dbData, branchState.GetWriteSession().GetOptions(), tCharacteristic), nil } // clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, @@ -463,13 +469,14 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er // isDirty returns whether the working set for the database named is dirty // TODO: remove the dbname parameter, return a global dirty bit +// TODO: re-evaluate dirty tracking like this altogether, use tx data func (d *DoltSession) isDirty(ctx *sql.Context, dbName string) (bool, error) { - dbState, _, err := d.LookupDbState(ctx, dbName) + branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return false, err } - - return dbState.dirty, nil + + return branchState.dbState.dirty, nil } // CommitWorkingSet commits the working set for the transaction given, without creating a new dolt commit. @@ -527,7 +534,7 @@ type doCommitFunc func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltd // doCommit exercise the business logic for a particular doCommitFunc func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transaction, commitFunc doCommitFunc) (*doltdb.Commit, error) { - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } else if !ok { @@ -543,7 +550,7 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti return nil, fmt.Errorf("expected a DoltTransaction") } - mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, dbState.GetWorkingSet()) + mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, branchState.GetWorkingSet()) if err != nil { return nil, err } @@ -553,7 +560,7 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti return nil, err } - dbState.dirty = false + branchState.dbState.dirty = false return newCommit, nil } @@ -577,17 +584,17 @@ func (d *DoltSession) PendingCommitAllStaged(ctx *sql.Context, dbName string, pr // merge parent from an in progress merge as appropriate. The session working set is not updated with these new roots, // but they are set in the returned |doltdb.PendingCommit|. If there are no changes staged, this method returns nil. func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots doltdb.Roots, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { - sessionState, _, err := d.LookupDbState(ctx, dbName) + branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } - headCommit := sessionState.headCommit + headCommit := branchState.headCommit headHash, _ := headCommit.HashOf() var mergeParentCommits []*doltdb.Commit - if sessionState.GetWorkingSet().MergeActive() { - mergeParentCommits = []*doltdb.Commit{sessionState.GetWorkingSet().MergeState().Commit()} + if branchState.GetWorkingSet().MergeActive() { + mergeParentCommits = []*doltdb.Commit{branchState.GetWorkingSet().MergeState().Commit()} } else if props.Amend { numParentsHeadForAmend := headCommit.NumParents() for i := 0; i < numParentsHeadForAmend; i++ { @@ -600,12 +607,12 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do // TODO: This is not the correct way to write this commit as an amend. While this commit is running // the branch head moves backwards and concurrency control here is not principled. - newRoots, err := actions.ResetSoftToRef(ctx, sessionState.dbData, "HEAD~1") + newRoots, err := actions.ResetSoftToRef(ctx, branchState.dbData, "HEAD~1") if err != nil { return nil, err } - err = d.SetWorkingSet(ctx, dbName, sessionState.GetWorkingSet().WithStagedRoot(newRoots.Staged)) + err = d.SetWorkingSet(ctx, dbName, branchState.GetWorkingSet().WithStagedRoot(newRoots.Staged)) if err != nil { return nil, err } @@ -613,10 +620,10 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do roots.Head = newRoots.Head } - pendingCommit, err := actions.GetCommitStaged(ctx, roots, sessionState.GetWorkingSet(), mergeParentCommits, sessionState.dbData.Ddb, props) + pendingCommit, err := actions.GetCommitStaged(ctx, roots, branchState.GetWorkingSet(), mergeParentCommits, branchState.dbData.Ddb, props) if err != nil { if props.Amend { - _, err = actions.ResetSoftToRef(ctx, sessionState.dbData, headHash.String()) + _, err = actions.ResetSoftToRef(ctx, branchState.dbData, headHash.String()) if err != nil { return nil, err } @@ -646,7 +653,7 @@ func (d *DoltSession) Rollback(ctx *sql.Context, tx sql.Transaction) error { return nil } - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return err } @@ -664,7 +671,7 @@ func (d *DoltSession) Rollback(ctx *sql.Context, tx sql.Transaction) error { return err } - dbState.dirty = false + branchState.dbState.dirty = false return nil } @@ -682,12 +689,12 @@ func (d *DoltSession) CreateSavepoint(ctx *sql.Context, tx sql.Transaction, save return fmt.Errorf("expected a DoltTransaction") } - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return err } - dtx.CreateSavepoint(savepointName, dbState.GetRoots().Working) + dtx.CreateSavepoint(savepointName, branchState.GetRoots().Working) return nil } @@ -742,7 +749,7 @@ func (d *DoltSession) ReleaseSavepoint(ctx *sql.Context, tx sql.Transaction, sav // GetDoltDB returns the *DoltDB for a given database by name func (d *DoltSession) GetDoltDB(ctx *sql.Context, dbName string) (*doltdb.DoltDB, bool) { - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, false } @@ -750,11 +757,11 @@ func (d *DoltSession) GetDoltDB(ctx *sql.Context, dbName string) (*doltdb.DoltDB return nil, false } - return dbState.dbData.Ddb, true + return branchState.dbData.Ddb, true } func (d *DoltSession) GetDbData(ctx *sql.Context, dbName string) (env.DbData, bool) { - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return env.DbData{}, false } @@ -762,12 +769,12 @@ func (d *DoltSession) GetDbData(ctx *sql.Context, dbName string) (env.DbData, bo return env.DbData{}, false } - return dbState.dbData, true + return branchState.dbData, true } // GetRoots returns the current roots for a given database associated with the session func (d *DoltSession) GetRoots(ctx *sql.Context, dbName string) (doltdb.Roots, bool) { - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return doltdb.Roots{}, false } @@ -775,7 +782,7 @@ func (d *DoltSession) GetRoots(ctx *sql.Context, dbName string) (doltdb.Roots, b return doltdb.Roots{}, false } - return dbState.GetRoots(), true + return branchState.GetRoots(), true } // ResolveRootForRef returns the root value for the ref given, which refers to either a commit spec or is one of the @@ -843,24 +850,25 @@ func (d *DoltSession) ResolveRootForRef(ctx *sql.Context, dbName, refStr string) // update the session's root value via this method. // Data changes contained in the |newRoot| aren't persisted until this session is committed. // TODO: rename to SetWorkingRoot +// TODO: kill this method func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.RootValue) error { // TODO: this is redundant with work done in setRoot - sessionState, _, err := d.LookupDbState(ctx, dbName) + branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return err } - if rootsEqual(sessionState.GetRoots().Working, newRoot) { + if rootsEqual(branchState.GetRoots().Working, newRoot) { return nil } - if sessionState.readOnly { + if branchState.readOnly { // TODO: Return an error here? return nil } - sessionState.WorkingSet = sessionState.GetWorkingSet().WithWorkingRoot(newRoot) + branchState.workingSet = branchState.GetWorkingSet().WithWorkingRoot(newRoot) - return d.SetWorkingSet(ctx, dbName, sessionState.GetWorkingSet()) + return d.SetWorkingSet(ctx, dbName, branchState.GetWorkingSet()) } // SetRoots sets new roots for the session for the database named. Typically clients should only set the working root, @@ -884,14 +892,14 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. panic("attempted to set a nil working set for the session") } - sessionState, _, err := d.LookupDbState(ctx, dbName) + branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return err } - if ws.Ref() != sessionState.GetWorkingSet().Ref() { + if ws.Ref() != branchState.GetWorkingSet().Ref() { return fmt.Errorf("must switch working sets with SwitchWorkingSet") } - sessionState.WorkingSet = ws + branchState.workingSet = ws cs, err := doltdb.NewCommitSpec(ws.Ref().GetPath()) if err != nil { @@ -903,29 +911,29 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return err } - cm, err := sessionState.dbData.Ddb.Resolve(ctx, cs, branchRef) + cm, err := branchState.dbData.Ddb.Resolve(ctx, cs, branchRef) if err != nil { return err } - sessionState.headCommit = cm + branchState.headCommit = cm headRoot, err := cm.GetRootValue(ctx) if err != nil { return err } - sessionState.headRoot = headRoot + branchState.headRoot = headRoot err = d.setSessionVarsForDb(ctx, dbName) if err != nil { return err } - err = sessionState.GetWriteSession().SetWorkingSet(ctx, ws) + err = branchState.GetWriteSession().SetWorkingSet(ctx, ws) if err != nil { return err } - sessionState.dirty = true + branchState.dbState.dirty = true return nil } @@ -940,13 +948,13 @@ func (d *DoltSession) SwitchWorkingSet( dbName string, wsRef ref.WorkingSetRef, ) error { - sessionState, _, err := d.LookupDbState(ctx, dbName) + branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return err } // TODO: should this be an error if any database in the transaction is dirty, or just this one? - if sessionState.dirty { + if branchState.dbState.dirty { return ErrWorkingSetChanges.New() } @@ -961,13 +969,13 @@ func (d *DoltSession) SwitchWorkingSet( } // TODO: resolve the working set ref with the root above - ws, err := sessionState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) + ws, err := branchState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) if err != nil { return err } // TODO: just call SetWorkingSet? - sessionState.WorkingSet = ws + branchState.workingSet = ws cs, err := doltdb.NewCommitSpec(ws.Ref().GetPath()) if err != nil { @@ -979,13 +987,13 @@ func (d *DoltSession) SwitchWorkingSet( return err } - cm, err := sessionState.dbData.Ddb.Resolve(ctx, cs, branchRef) + cm, err := branchState.dbData.Ddb.Resolve(ctx, cs, branchRef) if err != nil { return err } - sessionState.headCommit = cm - sessionState.headRoot, err = cm.GetRootValue(ctx) + branchState.headCommit = cm + branchState.headRoot, err = cm.GetRootValue(ctx) if err != nil { return err } @@ -1006,16 +1014,18 @@ func (d *DoltSession) SwitchWorkingSet( } // make a fresh WriteSession, discard existing WriteSession - opts := sessionState.GetWriteSession().GetOptions() + opts := branchState.GetWriteSession().GetOptions() nbf := ws.WorkingRoot().VRW().Format() - tracker, err := sessionState.globalState.GetAutoIncrementTracker(ctx) + tracker, err := branchState.dbState.globalState.GetAutoIncrementTracker(ctx) if err != nil { return err } - sessionState.WriteSession = writer.NewWriteSession(nbf, ws, tracker, opts) + branchState.writeSession = writer.NewWriteSession(nbf, ws, tracker, opts) // After switching to a new working set, we are by definition clean - sessionState.dirty = false + // TODO: obviously this is no longer true but this entire method needs a rewrite to tolerate writing to multiple + // heads in one tx + branchState.dbState.dirty = false // the current transaction, if there is one, needs to be restarted tCharacteristic := sql.ReadWrite @@ -1029,8 +1039,8 @@ func (d *DoltSession) SwitchWorkingSet( nomsRoots, ws, wsRef, - sessionState.dbData, - sessionState.GetWriteSession().GetOptions(), + branchState.dbData, + branchState.GetWriteSession().GetOptions(), tCharacteristic, )) @@ -1047,7 +1057,7 @@ func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.Worki // GetHeadCommit returns the parent commit of the current session. func (d *DoltSession) GetHeadCommit(ctx *sql.Context, dbName string) (*doltdb.Commit, error) { - dbState, ok, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } @@ -1055,7 +1065,7 @@ func (d *DoltSession) GetHeadCommit(ctx *sql.Context, dbName string) (*doltdb.Co return nil, sql.ErrDatabaseNotFound.New(dbName) } - return dbState.headCommit, nil + return branchState.headCommit, nil } // SetSessionVariable is defined on sql.Session. We intercept it here to interpret the special semantics of the system @@ -1110,17 +1120,22 @@ func (d *DoltSession) setForeignKeyChecksSessionVar(ctx *sql.Context, key string if convertedVal != nil { intVal = convertedVal.(int64) } + if intVal == 0 { for _, dbState := range d.dbStates { - opts := dbState.GetWriteSession().GetOptions() - opts.ForeignKeyChecksDisabled = true - dbState.GetWriteSession().SetOptions(opts) + for _, branchState := range dbState.heads { + opts := branchState.GetWriteSession().GetOptions() + opts.ForeignKeyChecksDisabled = true + branchState.GetWriteSession().SetOptions(opts) + } } } else if intVal == 1 { for _, dbState := range d.dbStates { - opts := dbState.GetWriteSession().GetOptions() - opts.ForeignKeyChecksDisabled = false - dbState.GetWriteSession().SetOptions(opts) + for _, branchState := range dbState.heads { + opts := branchState.GetWriteSession().GetOptions() + opts.ForeignKeyChecksDisabled = false + branchState.GetWriteSession().SetOptions(opts) + } } } else { return fmt.Errorf("variable 'foreign_key_checks' can't be set to the value of '%d'", intVal) @@ -1155,7 +1170,6 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if _, ok := d.dbStates[strings.ToLower(baseName)]; !ok { sessionState = NewEmptyDatabaseSessionState() d.dbStates[strings.ToLower(baseName)] = sessionState - sessionState.heads[strings.ToLower(rev)] = branchState tmpDir, err := dbState.DbData.Rsw.TempTableFilesDir() if err != nil { @@ -1166,6 +1180,8 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } sessionState.tmpFileDir = tmpDir } + branchState.dbState = sessionState + sessionState.heads[strings.ToLower(rev)] = branchState d.mu.Unlock() sessionState.dbName = baseName From 6800b9ebfc4af8c2a39760873d66d881658d2ffb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 09:35:06 -0700 Subject: [PATCH 008/167] Massaging the branch state interface --- go/libraries/doltcore/sqle/database.go | 4 +- .../dprocedures/dolt_conflicts_resolve.go | 2 +- .../sqle/dsess/database_session_state.go | 53 +++++++------- go/libraries/doltcore/sqle/dsess/session.go | 69 ++++++++++--------- .../sqle/dsess/session_state_adapter.go | 8 +-- .../doltcore/sqle/dtables/ignore_table.go | 6 +- go/libraries/doltcore/sqle/tables.go | 6 +- go/libraries/doltcore/sqle/temp_table.go | 4 +- 8 files changed, 79 insertions(+), 73 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 50a1e672c2..a93c724643 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -654,7 +654,7 @@ func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) { if !ok { return nil, fmt.Errorf("no root value found in session") } - return dbState.GetWorkingSet(), nil + return dbState.WorkingSet(), nil } // SetRoot should typically be called on the Session, which is where this state lives. But it's available here as a @@ -1010,7 +1010,7 @@ func (db Database) Flush(ctx *sql.Context) error { if err != nil { return err } - editSession := dbState.GetWriteSession() + editSession := dbState.WriteSession() ws, err := editSession.Flush(ctx) if err != nil { diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go b/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go index bdca65346b..9b782ed608 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go @@ -419,7 +419,7 @@ func ResolveDataConflicts(ctx *sql.Context, dSess *dsess.DoltSession, root *dolt if err != nil { return err } - opts := state.GetWriteSession().GetOptions() + opts := state.WriteSession().GetOptions() tbl, err = resolveNomsConflicts(ctx, opts, tbl, tblName, sch) } if err != nil { diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 04144fffa1..d5c74cec27 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -91,27 +91,18 @@ func NewEmptyDatabaseSessionState() *DatabaseSessionState { } } -func (d *DatabaseSessionState) SessionCache() *SessionCache { - return d.sessionCache -} - // SessionState is the public interface for dealing with session state outside this package. Session-state is always // branch-specific. type SessionState interface { - GetWorkingSet() *doltdb.WorkingSet - GetWriteSession() writer.WriteSession -} - -func (d *branchState) GetWorkingSet() *doltdb.WorkingSet { - return d.workingSet -} - -func (d *branchState) GetWriteSession() writer.WriteSession { - return d.writeSession + WorkingSet() *doltdb.WorkingSet + WriteSession() writer.WriteSession + EditOpts() editor.Options + SessionCache() *SessionCache } // branchState records all the in-memory session state for a particular branch head type branchState struct { + // dbState is the parent database state for this branch head state dbState *DatabaseSessionState // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which // case headRoot must be set. @@ -122,16 +113,34 @@ type branchState struct { // case headCommit must be set workingSet *doltdb.WorkingSet // dbData is an accessor for the underlying doltDb + // TODO: move this to DatabaseSessionState only dbData env.DbData - // writeSession is this database's write session, which changes when the working set changes + // writeSession is this head's write session writeSession writer.WriteSession - // globalState is the global state of this session (shared by all sessions for a particular db) // readOnly is true if this database is read only readOnly bool } -func (d branchState) GetRoots() doltdb.Roots { - if d.GetWorkingSet() == nil { +var _ SessionState = (*branchState)(nil) + +func (d *branchState) WorkingSet() *doltdb.WorkingSet { + return d.workingSet +} + +func (d *branchState) WriteSession() writer.WriteSession { + return d.writeSession +} + +func (d *branchState) SessionCache() *SessionCache { + return d.dbState.sessionCache +} + +func (d branchState) EditOpts() editor.Options { + return d.WriteSession().GetOptions() +} + +func (d branchState) roots() doltdb.Roots { + if d.WorkingSet() == nil { return doltdb.Roots{ Head: d.headRoot, Working: d.headRoot, @@ -140,11 +149,7 @@ func (d branchState) GetRoots() doltdb.Roots { } return doltdb.Roots{ Head: d.headRoot, - Working: d.GetWorkingSet().WorkingRoot(), - Staged: d.GetWorkingSet().StagedRoot(), + Working: d.WorkingSet().WorkingRoot(), + Staged: d.WorkingSet().StagedRoot(), } } - -func (d branchState) EditOpts() editor.Options { - return d.GetWriteSession().GetOptions() -} diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 1570590292..9dc161888a 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -134,7 +134,8 @@ func DSessFromSess(sess sql.Session) *DoltSession { return sess.(*DoltSession) } -// LookupDbState returns the session state for the database named +// lookupDbState is the private version of LookupDbState, returning a struct that has more information available than +// the interface returned by the public method. func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchState, bool, error) { // TODO: change to require a db, not a name? @@ -248,10 +249,10 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { if !ok { return nil } - if sessionState.GetWorkingSet() == nil { + if sessionState.WorkingSet() == nil { return nil } - wsRef := sessionState.GetWorkingSet().Ref() + wsRef := sessionState.WorkingSet().Ref() _, err = sessionState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) if err == doltdb.ErrWorkingSetNotFound { _, err = d.newWorkingSetForHead(ctx, wsRef, dbName) @@ -295,7 +296,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // There are both valid and invalid ways that a working set for the session state can be nil (e.g. connected to a // commit hash revision DB, or the DB contents cannot be loaded). Either way this transaction is defunct. // TODO: with multi-db transactions, such DBs should be ignored - if branchState.GetWorkingSet() == nil { + if branchState.WorkingSet() == nil { return DisabledTransaction{}, nil } @@ -339,7 +340,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - wsRef := branchState.GetWorkingSet().Ref() + wsRef := branchState.WorkingSet().Ref() ws, err := branchState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) // TODO: every HEAD needs a working set created when it is. We can get rid of this in a 1.0 release when this is fixed if err == doltdb.ErrWorkingSetNotFound { @@ -359,7 +360,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // SetWorkingSet always sets the dirty bit, but by definition we are clean at transaction start branchState.dbState.dirty = false - return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, branchState.dbData, branchState.GetWriteSession().GetOptions(), tCharacteristic), nil + return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, branchState.dbData, branchState.WriteSession().GetOptions(), tCharacteristic), nil } // clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, @@ -550,7 +551,7 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti return nil, fmt.Errorf("expected a DoltTransaction") } - mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, branchState.GetWorkingSet()) + mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, branchState.WorkingSet()) if err != nil { return nil, err } @@ -593,8 +594,8 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do headHash, _ := headCommit.HashOf() var mergeParentCommits []*doltdb.Commit - if branchState.GetWorkingSet().MergeActive() { - mergeParentCommits = []*doltdb.Commit{branchState.GetWorkingSet().MergeState().Commit()} + if branchState.WorkingSet().MergeActive() { + mergeParentCommits = []*doltdb.Commit{branchState.WorkingSet().MergeState().Commit()} } else if props.Amend { numParentsHeadForAmend := headCommit.NumParents() for i := 0; i < numParentsHeadForAmend; i++ { @@ -612,7 +613,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do return nil, err } - err = d.SetWorkingSet(ctx, dbName, branchState.GetWorkingSet().WithStagedRoot(newRoots.Staged)) + err = d.SetWorkingSet(ctx, dbName, branchState.WorkingSet().WithStagedRoot(newRoots.Staged)) if err != nil { return nil, err } @@ -620,7 +621,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do roots.Head = newRoots.Head } - pendingCommit, err := actions.GetCommitStaged(ctx, roots, branchState.GetWorkingSet(), mergeParentCommits, branchState.dbData.Ddb, props) + pendingCommit, err := actions.GetCommitStaged(ctx, roots, branchState.WorkingSet(), mergeParentCommits, branchState.dbData.Ddb, props) if err != nil { if props.Amend { _, err = actions.ResetSoftToRef(ctx, branchState.dbData, headHash.String()) @@ -694,7 +695,7 @@ func (d *DoltSession) CreateSavepoint(ctx *sql.Context, tx sql.Transaction, save return err } - dtx.CreateSavepoint(savepointName, branchState.GetRoots().Working) + dtx.CreateSavepoint(savepointName, branchState.roots().Working) return nil } @@ -782,7 +783,7 @@ func (d *DoltSession) GetRoots(ctx *sql.Context, dbName string) (doltdb.Roots, b return doltdb.Roots{}, false } - return branchState.GetRoots(), true + return branchState.roots(), true } // ResolveRootForRef returns the root value for the ref given, which refers to either a commit spec or is one of the @@ -858,7 +859,7 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R return err } - if rootsEqual(branchState.GetRoots().Working, newRoot) { + if rootsEqual(branchState.roots().Working, newRoot) { return nil } @@ -866,9 +867,9 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R // TODO: Return an error here? return nil } - branchState.workingSet = branchState.GetWorkingSet().WithWorkingRoot(newRoot) + branchState.workingSet = branchState.WorkingSet().WithWorkingRoot(newRoot) - return d.SetWorkingSet(ctx, dbName, branchState.GetWorkingSet()) + return d.SetWorkingSet(ctx, dbName, branchState.WorkingSet()) } // SetRoots sets new roots for the session for the database named. Typically clients should only set the working root, @@ -881,7 +882,7 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo return err } - workingSet := sessionState.GetWorkingSet().WithWorkingRoot(roots.Working).WithStagedRoot(roots.Staged) + workingSet := sessionState.WorkingSet().WithWorkingRoot(roots.Working).WithStagedRoot(roots.Staged) return d.SetWorkingSet(ctx, dbName, workingSet) } @@ -896,7 +897,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. if err != nil { return err } - if ws.Ref() != branchState.GetWorkingSet().Ref() { + if ws.Ref() != branchState.WorkingSet().Ref() { return fmt.Errorf("must switch working sets with SwitchWorkingSet") } branchState.workingSet = ws @@ -928,7 +929,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return err } - err = branchState.GetWriteSession().SetWorkingSet(ctx, ws) + err = branchState.WriteSession().SetWorkingSet(ctx, ws) if err != nil { return err } @@ -1014,7 +1015,7 @@ func (d *DoltSession) SwitchWorkingSet( } // make a fresh WriteSession, discard existing WriteSession - opts := branchState.GetWriteSession().GetOptions() + opts := branchState.WriteSession().GetOptions() nbf := ws.WorkingRoot().VRW().Format() tracker, err := branchState.dbState.globalState.GetAutoIncrementTracker(ctx) if err != nil { @@ -1040,7 +1041,7 @@ func (d *DoltSession) SwitchWorkingSet( ws, wsRef, branchState.dbData, - branchState.GetWriteSession().GetOptions(), + branchState.WriteSession().GetOptions(), tCharacteristic, )) @@ -1052,7 +1053,7 @@ func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.Worki if err != nil { return nil, err } - return sessionState.GetWorkingSet(), nil + return sessionState.WorkingSet(), nil } // GetHeadCommit returns the parent commit of the current session. @@ -1124,17 +1125,17 @@ func (d *DoltSession) setForeignKeyChecksSessionVar(ctx *sql.Context, key string if intVal == 0 { for _, dbState := range d.dbStates { for _, branchState := range dbState.heads { - opts := branchState.GetWriteSession().GetOptions() + opts := branchState.WriteSession().GetOptions() opts.ForeignKeyChecksDisabled = true - branchState.GetWriteSession().SetOptions(opts) + branchState.WriteSession().SetOptions(opts) } } } else if intVal == 1 { for _, dbState := range d.dbStates { for _, branchState := range dbState.heads { - opts := branchState.GetWriteSession().GetOptions() + opts := branchState.WriteSession().GetOptions() opts.ForeignKeyChecksDisabled = false - branchState.GetWriteSession().SetOptions(opts) + branchState.WriteSession().SetOptions(opts) } } } else { @@ -1223,7 +1224,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if err != nil { return err } - branchState.writeSession = writer.NewWriteSession(nbf, branchState.GetWorkingSet(), tracker, editOpts) + branchState.writeSession = writer.NewWriteSession(nbf, branchState.WorkingSet(), tracker, editOpts) if err = d.SetWorkingSet(ctx, db.Name(), dbState.WorkingSet); err != nil { return err } @@ -1288,11 +1289,11 @@ func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef, return nil, err } - if dbState.GetWorkingSet() == nil { + if dbState.WorkingSet() == nil { return nil, nil } - return dbState.GetWorkingSet().Ref().ToHeadRef() + return dbState.WorkingSet().Ref().ToHeadRef() } func (d *DoltSession) Username() string { @@ -1316,8 +1317,8 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string) error // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here - if state.GetWorkingSet() != nil { - headRef, err := state.GetWorkingSet().Ref().ToHeadRef() + if state.WorkingSet() != nil { + headRef, err := state.WorkingSet().Ref().ToHeadRef() if err != nil { return err } @@ -1328,7 +1329,7 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string) error } } - roots := state.GetRoots() + roots := state.roots() if roots.Working != nil { h, err := roots.Working.HashOf() @@ -1458,8 +1459,8 @@ func (d *DoltSession) GetBranch() (string, error) { return "", err } - if dbState.GetWorkingSet() != nil { - branchRef, err := dbState.GetWorkingSet().Ref().ToHeadRef() + if dbState.WorkingSet() != nil { + branchRef, err := dbState.WorkingSet().Ref().ToHeadRef() if err != nil { return "", err } diff --git a/go/libraries/doltcore/sqle/dsess/session_state_adapter.go b/go/libraries/doltcore/sqle/dsess/session_state_adapter.go index 5bb8967043..3ab2164b81 100644 --- a/go/libraries/doltcore/sqle/dsess/session_state_adapter.go +++ b/go/libraries/doltcore/sqle/dsess/session_state_adapter.go @@ -53,12 +53,12 @@ func NewSessionStateAdapter(session *DoltSession, dbName string, remotes map[str func (s SessionStateAdapter) GetRoots(ctx context.Context) (doltdb.Roots, error) { sqlCtx := sql.NewContext(ctx) - state, _, err := s.session.LookupDbState(sqlCtx, s.dbName) + state, _, err := s.session.lookupDbState(sqlCtx, s.dbName) if err != nil { return doltdb.Roots{}, err } - return state.GetRoots(), nil + return state.roots(), nil } func (s SessionStateAdapter) CWBHeadRef() ref.DoltRef { @@ -226,10 +226,10 @@ func (s SessionStateAdapter) RemoveBackup(_ context.Context, name string) error } func (s SessionStateAdapter) TempTableFilesDir() (string, error) { - state, _, err := s.session.LookupDbState(sql.NewContext(context.Background()), s.dbName) + branchState, _, err := s.session.lookupDbState(sql.NewContext(context.Background()), s.dbName) if err != nil { return "", err } - return state.tmpFileDir, nil + return branchState.dbState.tmpFileDir, nil } diff --git a/go/libraries/doltcore/sqle/dtables/ignore_table.go b/go/libraries/doltcore/sqle/dtables/ignore_table.go index 39fc783d8b..57e93201ed 100644 --- a/go/libraries/doltcore/sqle/dtables/ignore_table.go +++ b/go/libraries/doltcore/sqle/dtables/ignore_table.go @@ -179,7 +179,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { iw.prevHash = &prevHash - iw.workingSet = dbState.GetWorkingSet() + iw.workingSet = dbState.WorkingSet() found, err := roots.Working.HasTable(ctx, doltdb.IgnoreTableName) if err != nil { @@ -232,7 +232,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { // We use WriteSession.SetWorkingSet instead of DoltSession.SetRoot because we want to avoid modifying the root // until the end of the transaction, but we still want the WriteSession to be able to find the newly // created table. - err = dbState.GetWriteSession().SetWorkingSet(ctx, dbState.GetWorkingSet().WithWorkingRoot(newRootValue)) + err = dbState.WriteSession().SetWorkingSet(ctx, dbState.WorkingSet().WithWorkingRoot(newRootValue)) if err != nil { iw.errDuringStatementBegin = err return @@ -241,7 +241,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { dSess.SetRoot(ctx, dbName, newRootValue) } - tableWriter, err := dbState.GetWriteSession().GetTableWriter(ctx, doltdb.IgnoreTableName, dbName, dSess.SetRoot, false) + tableWriter, err := dbState.WriteSession().GetTableWriter(ctx, doltdb.IgnoreTableName, dbName, dSess.SetRoot, false) if err != nil { iw.errDuringStatementBegin = err return diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 10173bb1d3..34bae29e99 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -526,7 +526,7 @@ func (t *WritableDoltTable) getTableEditor(ctx *sql.Context) (ed writer.TableWri } setter := ds.SetRoot - ed, err = state.GetWriteSession().GetTableWriter(ctx, t.tableName, t.db.Name(), setter, batched) + ed, err = state.WriteSession().GetTableWriter(ctx, t.tableName, t.db.Name(), setter, batched) if err != nil { return nil, err @@ -1257,7 +1257,7 @@ func (t *AlterableDoltTable) RewriteInserter( return nil, fmt.Errorf("database %s not found in session", t.db.Name()) } - ws := dbState.GetWorkingSet() + ws := dbState.WorkingSet() head, err := sess.GetHeadCommit(ctx, t.db.Name()) if err != nil { @@ -1363,7 +1363,7 @@ func (t *AlterableDoltTable) RewriteInserter( // We can't just call getTableEditor here because it uses the session state, which we can't update until after the // rewrite operation - opts := dbState.GetWriteSession().GetOptions() + opts := dbState.WriteSession().GetOptions() opts.ForeignKeyChecksDisabled = true newRoot, err := ws.WorkingRoot().PutTable(ctx, t.Name(), dt) diff --git a/go/libraries/doltcore/sqle/temp_table.go b/go/libraries/doltcore/sqle/temp_table.go index 3e52a6c2fa..73aaf8e5e9 100644 --- a/go/libraries/doltcore/sqle/temp_table.go +++ b/go/libraries/doltcore/sqle/temp_table.go @@ -78,7 +78,7 @@ func NewTempTable( return nil, fmt.Errorf("database %s not found in session", db) } - ws := dbState.GetWorkingSet() + ws := dbState.WorkingSet() sch, err := temporaryDoltSchema(ctx, pkSch, collation) if err != nil { @@ -152,7 +152,7 @@ func setTempTableRoot(t *TempTable) func(ctx *sql.Context, dbName string, newRoo return fmt.Errorf("database %s not found in session", t.dbName) } - ws := dbState.GetWorkingSet() + ws := dbState.WorkingSet() newWs := ws.WithWorkingRoot(newRoot) ait, err := globalstate.NewAutoIncrementTracker(ctx, newWs) From 09b02f12cab88de6f9368c131331db1cd76407be Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 10:09:04 -0700 Subject: [PATCH 009/167] Added workingRoot method --- go/libraries/doltcore/sqle/database.go | 2 +- go/libraries/doltcore/sqle/dsess/database_session_state.go | 7 ++++++- go/libraries/doltcore/sqle/dsess/session.go | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index a93c724643..97e6e60a77 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -642,7 +642,7 @@ func (db Database) GetRoot(ctx *sql.Context) (*doltdb.RootValue, error) { return nil, fmt.Errorf("no root value found in session") } - return dbState.GetRoots().Working, nil + return dbState.WorkingRoot(), nil } func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) { diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index d5c74cec27..ce27dedad5 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -95,6 +95,7 @@ func NewEmptyDatabaseSessionState() *DatabaseSessionState { // branch-specific. type SessionState interface { WorkingSet() *doltdb.WorkingSet + WorkingRoot() *doltdb.RootValue WriteSession() writer.WriteSession EditOpts() editor.Options SessionCache() *SessionCache @@ -121,6 +122,10 @@ type branchState struct { readOnly bool } +func (d *branchState) WorkingRoot() *doltdb.RootValue { + return d.roots().Working +} + var _ SessionState = (*branchState)(nil) func (d *branchState) WorkingSet() *doltdb.WorkingSet { @@ -139,7 +144,7 @@ func (d branchState) EditOpts() editor.Options { return d.WriteSession().GetOptions() } -func (d branchState) roots() doltdb.Roots { +func (d *branchState) roots() doltdb.Roots { if d.WorkingSet() == nil { return doltdb.Roots{ Head: d.headRoot, diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 9dc161888a..e8818e6c32 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -213,12 +213,12 @@ func (d *DoltSession) RemoveDbState(_ *sql.Context, dbName string) error { // happens automatically as part of statement execution, and is only necessary when the session is manually batched (as // for bulk SQL import) func (d *DoltSession) Flush(ctx *sql.Context, dbName string) error { - dbState, _, err := d.LookupDbState(ctx, dbName) + branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return err } - ws, err := dbState.GetWriteSession().Flush(ctx) + ws, err := branchState.WriteSession().Flush(ctx) if err != nil { return err } From d8c96dfe8c833883cdbe35d622f11acb8e26577e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 11:10:57 -0700 Subject: [PATCH 010/167] Crossing the rubicon --- go/libraries/doltcore/sqle/dsess/session.go | 100 +++++------------- .../doltcore/sqle/dsess/transactions.go | 11 ++ 2 files changed, 35 insertions(+), 76 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index e8818e6c32..fcbbec5771 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -270,59 +270,36 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { // StartTransaction refreshes the state of this session and starts a new transaction. func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.TransactionCharacteristic) (sql.Transaction, error) { - if TransactionsDisabled(ctx) { - return DisabledTransaction{}, nil - } - - // TODO: remove this when we have true multi-db transaction support - dbName := ctx.GetTransactionDatabase() - if isNoOpTransactionDatabase(dbName) { - return DisabledTransaction{}, nil - } - // New transaction, clear all session state // TODO: revisit this d.clearRevisionDbState() - branchState, ok, err := d.lookupDbState(ctx, dbName) - if err != nil { - return nil, err - } - - if !ok { - return nil, sql.ErrDatabaseNotFound.New(dbName) - } - - // There are both valid and invalid ways that a working set for the session state can be nil (e.g. connected to a - // commit hash revision DB, or the DB contents cannot be loaded). Either way this transaction is defunct. - // TODO: with multi-db transactions, such DBs should be ignored - if branchState.WorkingSet() == nil { - return DisabledTransaction{}, nil - } - - // TODO: this needs to happen for every DB in the database, not just the one named in the transaction - if branchState != nil && branchState.dbState.db != nil { - rrd, ok := branchState.dbState.db.(RemoteReadReplicaDatabase) - if ok && rrd.ValidReplicaState(ctx) { - err := rrd.PullFromRemote(ctx) - if err != nil && !IgnoreReplicationErrors() { - return nil, fmt.Errorf("replication error: %w", err) - } else if err != nil { - WarnReplicationError(ctx, err) - } - } - } - - if branchState.readOnly { - return DisabledTransaction{}, nil - } - + // Take a snapshot of the current noms root for every database under management nomsRoots := make(map[string]hash.Hash) for _, db := range d.provider.DoltDatabases() { - // TODO: this is only necessary to support UserSpaceDatabase, come up with a better set of interfaces to capture - // these capabilities + // TODO: this nil check is only necessary to support UserSpaceDatabase, come up with a better set of interfaces + // to capture these capabilities ddb := db.DbData().Ddb if ddb != nil { + rrd, ok := db.(RemoteReadReplicaDatabase) + if ok && rrd.ValidReplicaState(ctx) { + err := rrd.PullFromRemote(ctx) + if err != nil && !IgnoreReplicationErrors() { + return nil, fmt.Errorf("replication error: %w", err) + } else if err != nil { + WarnReplicationError(ctx, err) + } + } + + if _, v, ok := sql.SystemVariables.GetGlobal(ReadReplicaRemote); ok && v != "" { + err := ddb.Rebase(ctx) + if err != nil && !IgnoreReplicationErrors() { + return nil, err + } else if err != nil { + WarnReplicationError(ctx, err) + } + } + nomsRoot, err := ddb.NomsRoot(ctx) if err != nil { return nil, err @@ -330,37 +307,8 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra nomsRoots[strings.ToLower(db.Name())] = nomsRoot } } - - if _, v, ok := sql.SystemVariables.GetGlobal(ReadReplicaRemote); ok && v != "" { - err = branchState.dbData.Ddb.Rebase(ctx) - if err != nil && !IgnoreReplicationErrors() { - return nil, err - } else if err != nil { - WarnReplicationError(ctx, err) - } - } - - wsRef := branchState.WorkingSet().Ref() - ws, err := branchState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) - // TODO: every HEAD needs a working set created when it is. We can get rid of this in a 1.0 release when this is fixed - if err == doltdb.ErrWorkingSetNotFound { - ws, err = d.newWorkingSetForHead(ctx, wsRef, dbName) - if err != nil { - return nil, err - } - } else if err != nil { - return nil, err - } - - // logrus.Tracef("starting transaction with working root %s", ws.WorkingRoot().DebugString(ctx, true)) - - // TODO: this is going to do 2 resolves to get the head root, not ideal - err = d.SetWorkingSet(ctx, dbName, ws) - - // SetWorkingSet always sets the dirty bit, but by definition we are clean at transaction start - branchState.dbState.dirty = false - - return NewDoltTransaction(dbName, nomsRoots, ws, wsRef, branchState.dbData, branchState.WriteSession().GetOptions(), tCharacteristic), nil + + return NewMultiHeadTransaction(nomsRoots, tCharacteristic), nil } // clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index f3786e2379..bd08298a64 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -85,6 +85,7 @@ type DoltTransaction struct { type savepoint struct { name string + // TODO: we need a root value per DB here root *doltdb.RootValue } @@ -108,6 +109,16 @@ func NewDoltTransaction( } } +func NewMultiHeadTransaction( + startingRoots map[string]hash.Hash, + tCharacteristic sql.TransactionCharacteristic, +) *DoltTransaction { + return &DoltTransaction{ + startRootHash: startingRoots, + tCharacteristic: tCharacteristic, + } +} + func (tx DoltTransaction) String() string { // TODO: return more info (hashes need caching) return "DoltTransaction" From 4b4ac108f19addfdc8d4e06831474421cbfa1ebd Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 11:58:31 -0700 Subject: [PATCH 011/167] Resolve the start working set at commit time, not at tx init time --- go/libraries/doltcore/sqle/dsess/session.go | 48 +------ .../doltcore/sqle/dsess/transactions.go | 136 ++++++++++++------ 2 files changed, 95 insertions(+), 89 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index fcbbec5771..667ce63174 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -441,7 +441,7 @@ func (d *DoltSession) CommitWorkingSet(ctx *sql.Context, dbName string, tx sql.T } commitFunc := func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, *doltdb.Commit, error) { - ws, err := dtx.Commit(ctx, workingSet) + ws, err := dtx.Commit(ctx, workingSet, dbName) return ws, nil, err } @@ -587,40 +587,8 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do // Rollback rolls the given transaction back func (d *DoltSession) Rollback(ctx *sql.Context, tx sql.Transaction) error { - dbName := ctx.GetTransactionDatabase() - - if TransactionsDisabled(ctx) || dbName == "" { - return nil - } - - dirty, err := d.isDirty(ctx, dbName) - if err != nil { - return err - } - - if !dirty { - return nil - } - - branchState, ok, err := d.lookupDbState(ctx, dbName) - if err != nil { - return err - } - - dtx, ok := tx.(*DoltTransaction) - if !ok { - return fmt.Errorf("expected a DoltTransaction") - } - - // This operation usually doesn't matter, because the engine will process a `rollback` statement by first calling - // this logic, then discarding any current transaction. So the next statement will get a fresh transaction regardless, - // and this is throwaway work. It only matters if this method is used outside a standalone `rollback` statement. - err = d.SetRoot(ctx, dbName, dtx.startState.WorkingRoot()) - if err != nil { - return err - } - - branchState.dbState.dirty = false + // Nothing to do here, we just throw away all our work and let a new transaction begin next statement + d.clearRevisionDbState() return nil } @@ -983,15 +951,7 @@ func (d *DoltSession) SwitchWorkingSet( tCharacteristic = sql.ReadOnly } } - ctx.SetTransaction(NewDoltTransaction( - dbName, - nomsRoots, - ws, - wsRef, - branchState.dbData, - branchState.WriteSession().GetOptions(), - tCharacteristic, - )) + ctx.SetTransaction(NewDoltTransaction(nomsRoots, ws, wsRef, branchState.dbData, branchState.WriteSession().GetOptions(), tCharacteristic)) return nil } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index bd08298a64..4a025311aa 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -73,8 +73,7 @@ func (d DisabledTransaction) IsReadOnly() bool { } type DoltTransaction struct { - sourceDbName string - startRootHash map[string]hash.Hash + dbStartPoints map[string]dbRoot startState *doltdb.WorkingSet workingSetRef ref.WorkingSetRef dbData env.DbData @@ -83,24 +82,28 @@ type DoltTransaction struct { tCharacteristic sql.TransactionCharacteristic } +type dbRoot struct { + dbName string + rootHash hash.Hash + db *doltdb.DoltDB +} + type savepoint struct { name string // TODO: we need a root value per DB here root *doltdb.RootValue } +// TODO: find refs to this and remove func NewDoltTransaction( - dbName string, - startingRoots map[string]hash.Hash, - startState *doltdb.WorkingSet, - workingSet ref.WorkingSetRef, - dbData env.DbData, - mergeEditOpts editor.Options, - tCharacteristic sql.TransactionCharacteristic, + startingRoots map[string]hash.Hash, + startState *doltdb.WorkingSet, + workingSet ref.WorkingSetRef, + dbData env.DbData, + mergeEditOpts editor.Options, + tCharacteristic sql.TransactionCharacteristic, ) *DoltTransaction { return &DoltTransaction{ - sourceDbName: dbName, - startRootHash: startingRoots, startState: startState, workingSetRef: workingSet, dbData: dbData, @@ -110,13 +113,33 @@ func NewDoltTransaction( } func NewMultiHeadTransaction( - startingRoots map[string]hash.Hash, + ctx *sql.Context, + dbs []SqlDatabase, tCharacteristic sql.TransactionCharacteristic, -) *DoltTransaction { - return &DoltTransaction{ - startRootHash: startingRoots, - tCharacteristic: tCharacteristic, +) (*DoltTransaction, error) { + + startPoints := make(map[string]dbRoot) + for _, db := range dbs { + ddb := db.DbData().Ddb + // TODO: this nil check is only here to accommodate user-space databases, find a better interface to exclude them + if ddb != nil { + nomsRoot, err := ddb.NomsRoot(ctx) + if err != nil { + return nil, err + } + + startPoints[strings.ToLower(db.Name())] = dbRoot{ + dbName: db.Name(), + rootHash: nomsRoot, + db: ddb, + } + } } + + return &DoltTransaction{ + dbStartPoints: startPoints, + tCharacteristic: tCharacteristic, + }, nil } func (tx DoltTransaction) String() string { @@ -129,8 +152,8 @@ func (tx DoltTransaction) IsReadOnly() bool { } func (tx DoltTransaction) GetInitialRoot(dbName string) (hash.Hash, bool) { - h, ok := tx.startRootHash[strings.ToLower(dbName)] - return h, ok + startPoint, ok := tx.dbStartPoints[strings.ToLower(dbName)] + return startPoint.rootHash, ok } var txLock sync.Mutex @@ -143,14 +166,16 @@ var txLock sync.Mutex // if workingSet.workingRoot == ancRoot, attempt a fast-forward merge // TODO: Non-working roots aren't merged into the working set and just stomp any changes made there. We need merge // strategies for staged as well as merge state. -func (tx *DoltTransaction) Commit(ctx *sql.Context, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, error) { - ws, _, err := tx.doCommit(ctx, workingSet, nil, txCommit) +func (tx *DoltTransaction) Commit(ctx *sql.Context, workingSet *doltdb.WorkingSet, dbName string) (*doltdb.WorkingSet, error) { + ws, _, err := tx.doCommit(ctx, workingSet, nil, txCommit, dbName) return ws, err } // transactionWrite is the logic to write an updated working set (and optionally a commit) to the database type transactionWrite func(ctx *sql.Context, tx *DoltTransaction, // the transaction being written + doltDb *doltdb.DoltDB, // the database to write to + startState *doltdb.WorkingSet, // the starting working set commit *doltdb.PendingCommit, // optional workingSet *doltdb.WorkingSet, // must be provided hash hash.Hash, // hash of the current working set to be written @@ -158,10 +183,12 @@ type transactionWrite func(ctx *sql.Context, // doltCommit is a transactionWrite function that updates the working set and commits a pending commit atomically func doltCommit(ctx *sql.Context, - tx *DoltTransaction, - commit *doltdb.PendingCommit, - workingSet *doltdb.WorkingSet, - currHash hash.Hash, + tx *DoltTransaction, // the transaction being written + doltDb *doltdb.DoltDB, // the database to write to + startState *doltdb.WorkingSet, // the starting working set + commit *doltdb.PendingCommit, // optional + workingSet *doltdb.WorkingSet, // must be provided + currHash hash.Hash, // hash of the current working set to be written ) (*doltdb.WorkingSet, *doltdb.Commit, error) { pending := *commit @@ -210,7 +237,7 @@ func doltCommit(ctx *sql.Context, curRootVal, pending.Roots.Head, curHead, - tx.startState, + startState, tx.mergeEditOpts, merge.MergeOpts{}) if err != nil { @@ -227,33 +254,51 @@ func doltCommit(ctx *sql.Context, workingSet = workingSet.ClearMerge() - newCommit, err := tx.dbData.Ddb.CommitWithWorkingSet(ctx, headRef, tx.workingSetRef, &pending, workingSet, currHash, tx.getWorkingSetMeta(ctx)) + newCommit, err := doltDb.CommitWithWorkingSet(ctx, headRef, tx.workingSetRef, &pending, workingSet, currHash, tx.getWorkingSetMeta(ctx)) return workingSet, newCommit, err } // txCommit is a transactionWrite function that updates the working set func txCommit(ctx *sql.Context, - tx *DoltTransaction, - _ *doltdb.PendingCommit, - workingSet *doltdb.WorkingSet, - hash hash.Hash, + tx *DoltTransaction, // the transaction being written + doltDb *doltdb.DoltDB, // the database to write to + _ *doltdb.WorkingSet, // the starting working set + _ *doltdb.PendingCommit, // optional + workingSet *doltdb.WorkingSet, // must be provided + hash hash.Hash, // hash of the current working set to be written ) (*doltdb.WorkingSet, *doltdb.Commit, error) { - return workingSet, nil, tx.dbData.Ddb.UpdateWorkingSet(ctx, tx.workingSetRef, workingSet, hash, tx.getWorkingSetMeta(ctx)) + return workingSet, nil, doltDb.UpdateWorkingSet(ctx, workingSet.Ref(), workingSet, hash, tx.getWorkingSetMeta(ctx)) } // DoltCommit commits the working set and creates a new DoltCommit as specified, in one atomic write -func (tx *DoltTransaction) DoltCommit(ctx *sql.Context, workingSet *doltdb.WorkingSet, commit *doltdb.PendingCommit) (*doltdb.WorkingSet, *doltdb.Commit, error) { - return tx.doCommit(ctx, workingSet, commit, doltCommit) +func (tx *DoltTransaction) DoltCommit( + ctx *sql.Context, + workingSet *doltdb.WorkingSet, + commit *doltdb.PendingCommit, +) (*doltdb.WorkingSet, *doltdb.Commit, error) { + return tx.doCommit(ctx, workingSet, commit, doltCommit, "") } // doCommit commits this transaction with the write function provided. It takes the same params as DoltCommit func (tx *DoltTransaction) doCommit( - ctx *sql.Context, - workingSet *doltdb.WorkingSet, - commit *doltdb.PendingCommit, - writeFn transactionWrite, + ctx *sql.Context, + workingSet *doltdb.WorkingSet, + commit *doltdb.PendingCommit, + writeFn transactionWrite, + dbName string, ) (*doltdb.WorkingSet, *doltdb.Commit, error) { + // Load the start state for this working set from the noms root at tx start + startPoint, ok := tx.dbStartPoints[strings.ToLower(dbName)] + if !ok { + return nil, nil, fmt.Errorf("database %s unknown to transaction, this is a bug", dbName) + } + + startState, err := startPoint.db.ResolveWorkingSetAtRoot(ctx, workingSet.Ref(), startPoint.rootHash) + if err != nil { + return nil, nil, err + } + for i := 0; i < maxTxCommitRetries; i++ { updatedWs, newCommit, err := func() (*doltdb.WorkingSet, *doltdb.Commit, error) { // Serialize commits, since only one can possibly succeed at a time anyway @@ -277,7 +322,7 @@ func (tx *DoltTransaction) doCommit( return nil, nil, err } - if newWorkingSet || workingAndStagedEqual(existingWs, tx.startState) { + if newWorkingSet || workingAndStagedEqual(existingWs, startState) { // ff merge err = tx.validateWorkingSetForCommit(ctx, workingSet, isFfMerge) if err != nil { @@ -285,7 +330,7 @@ func (tx *DoltTransaction) doCommit( } var newCommit *doltdb.Commit - workingSet, newCommit, err = writeFn(ctx, tx, commit, workingSet, existingWSHash) + workingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, workingSet, existingWSHash) if err == datas.ErrOptimisticLockFailed { // this is effectively a `continue` in the loop return nil, nil, nil @@ -298,7 +343,7 @@ func (tx *DoltTransaction) doCommit( // otherwise (not a ff), merge the working sets together start := time.Now() - mergedWorkingSet, err := tx.mergeRoots(ctx, existingWs, workingSet) + mergedWorkingSet, err := tx.mergeRoots(ctx, startState, existingWs, workingSet) if err != nil { return nil, nil, err } @@ -310,7 +355,7 @@ func (tx *DoltTransaction) doCommit( } var newCommit *doltdb.Commit - mergedWorkingSet, newCommit, err = writeFn(ctx, tx, commit, mergedWorkingSet, existingWSHash) + mergedWorkingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, mergedWorkingSet, existingWSHash) if err == datas.ErrOptimisticLockFailed { // this is effectively a `continue` in the loop return nil, nil, nil @@ -337,6 +382,7 @@ func (tx *DoltTransaction) doCommit( // Currently merges working and staged roots as necessary. HEAD root is only handled by the DoltCommit function. func (tx *DoltTransaction) mergeRoots( ctx *sql.Context, + startState *doltdb.WorkingSet, existingWorkingSet *doltdb.WorkingSet, workingSet *doltdb.WorkingSet, ) (*doltdb.WorkingSet, error) { @@ -346,9 +392,9 @@ func (tx *DoltTransaction) mergeRoots( ctx, existingWorkingSet.WorkingRoot(), workingSet.WorkingRoot(), - tx.startState.WorkingRoot(), + startState.WorkingRoot(), workingSet, - tx.startState, + startState, tx.mergeEditOpts, merge.MergeOpts{}) if err != nil { @@ -362,9 +408,9 @@ func (tx *DoltTransaction) mergeRoots( ctx, existingWorkingSet.StagedRoot(), workingSet.StagedRoot(), - tx.startState.StagedRoot(), + startState.StagedRoot(), workingSet, - tx.startState, + startState, tx.mergeEditOpts, merge.MergeOpts{}) if err != nil { From 95795c1986197956369b495bbd1b5d8b381f52ea Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 14:02:53 -0700 Subject: [PATCH 012/167] Refining some init / commit logic --- go/libraries/doltcore/sqle/dsess/session.go | 66 ++++++++----------- .../doltcore/sqle/dsess/transactions.go | 22 +++---- 2 files changed, 36 insertions(+), 52 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 667ce63174..436f94d0b2 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -22,7 +22,7 @@ import ( "strings" "sync" "time" - + "github.com/dolthub/go-mysql-server/sql" sqltypes "github.com/dolthub/go-mysql-server/sql/types" goerrors "gopkg.in/src-d/go-errors.v1" @@ -137,29 +137,30 @@ func DSessFromSess(sess sql.Session) *DoltSession { // lookupDbState is the private version of LookupDbState, returning a struct that has more information available than // the interface returned by the public method. func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchState, bool, error) { - // TODO: change to require a db, not a name? - + // TODO: change to require a db, not a name so that the below doesn't need to do a string split dbName = strings.ToLower(dbName) + + parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) + baseName := parts[0] + d.mu.Lock() - dbState, ok := d.dbStates[dbName] + dbState, ok := d.dbStates[baseName] d.mu.Unlock() - if !ok { - return nil, false, nil - } - - _, rev := SplitRevisionDbName(dbState.db) - branchState, ok := dbState.heads[strings.ToLower(rev)] - if ok { - if dbState.Err != nil { - return nil, false, dbState.Err - } - - // TODO: fill in - return branchState, ok, nil - } + _, rev := SplitRevisionDbName(dbState.db) + branchState, ok := dbState.heads[strings.ToLower(rev)] + if ok { + if dbState.Err != nil { + return nil, false, dbState.Err + } + + return branchState, ok, nil + } + } + + // no state for this db / branch combination yet, look it up from the provider database, ok, err := d.provider.SessionDatabase(ctx, dbName) if err != nil { return nil, false, err @@ -181,9 +182,8 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta return nil, false, sql.ErrDatabaseNotFound.New(dbName) } - branchState = dbState.heads[strings.ToLower(rev)] - - return branchState, true, nil + _, rev := SplitRevisionDbName(database) + return dbState.heads[strings.ToLower(rev)], true, nil } // TODO NEXT: the lookupdbstate method is the key abstraction point. It proxies all non-revisoined DBs to a revisioned @@ -275,8 +275,9 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra d.clearRevisionDbState() // Take a snapshot of the current noms root for every database under management - nomsRoots := make(map[string]hash.Hash) - for _, db := range d.provider.DoltDatabases() { + doltDatabases := d.provider.DoltDatabases() + txDbs := make([]SqlDatabase, 0, len(doltDatabases)) + for _, db := range doltDatabases { // TODO: this nil check is only necessary to support UserSpaceDatabase, come up with a better set of interfaces // to capture these capabilities ddb := db.DbData().Ddb @@ -300,15 +301,11 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - nomsRoot, err := ddb.NomsRoot(ctx) - if err != nil { - return nil, err - } - nomsRoots[strings.ToLower(db.Name())] = nomsRoot + txDbs = append(txDbs, db) } } - return NewMultiHeadTransaction(nomsRoots, tCharacteristic), nil + return NewMultiHeadTransaction(ctx, txDbs, tCharacteristic) } // clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, @@ -431,21 +428,12 @@ func (d *DoltSession) isDirty(ctx *sql.Context, dbName string) (bool, error) { // CommitWorkingSet commits the working set for the transaction given, without creating a new dolt commit. // Clients should typically use CommitTransaction, which performs additional checks, instead of this method. func (d *DoltSession) CommitWorkingSet(ctx *sql.Context, dbName string, tx sql.Transaction) error { - dirty, err := d.isDirty(ctx, dbName) - if err != nil { - return err - } - - if !dirty { - return nil - } - commitFunc := func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, *doltdb.Commit, error) { ws, err := dtx.Commit(ctx, workingSet, dbName) return ws, nil, err } - _, err = d.doCommit(ctx, dbName, tx, commitFunc) + _, err := d.doCommit(ctx, dbName, tx, commitFunc) return err } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 4a025311aa..38bcc6e0d8 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -120,22 +120,18 @@ func NewMultiHeadTransaction( startPoints := make(map[string]dbRoot) for _, db := range dbs { - ddb := db.DbData().Ddb - // TODO: this nil check is only here to accommodate user-space databases, find a better interface to exclude them - if ddb != nil { - nomsRoot, err := ddb.NomsRoot(ctx) - if err != nil { - return nil, err - } + nomsRoot, err := db.DbData().Ddb.NomsRoot(ctx) + if err != nil { + return nil, err + } - startPoints[strings.ToLower(db.Name())] = dbRoot{ - dbName: db.Name(), - rootHash: nomsRoot, - db: ddb, - } + startPoints[strings.ToLower(db.Name())] = dbRoot{ + dbName: db.Name(), + rootHash: nomsRoot, + db: db.DbData().Ddb, } } - + return &DoltTransaction{ dbStartPoints: startPoints, tCharacteristic: tCharacteristic, From 754952e4c387c7e62a1404a57d1a30cbb0bb4953 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 14:30:24 -0700 Subject: [PATCH 013/167] Kill working set ref in tx --- go/libraries/doltcore/sqle/dsess/transactions.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 38bcc6e0d8..34ed881a2d 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -75,7 +75,6 @@ func (d DisabledTransaction) IsReadOnly() bool { type DoltTransaction struct { dbStartPoints map[string]dbRoot startState *doltdb.WorkingSet - workingSetRef ref.WorkingSetRef dbData env.DbData savepoints []savepoint mergeEditOpts editor.Options @@ -105,7 +104,6 @@ func NewDoltTransaction( ) *DoltTransaction { return &DoltTransaction{ startState: startState, - workingSetRef: workingSet, dbData: dbData, mergeEditOpts: mergeEditOpts, tCharacteristic: tCharacteristic, @@ -250,7 +248,7 @@ func doltCommit(ctx *sql.Context, workingSet = workingSet.ClearMerge() - newCommit, err := doltDb.CommitWithWorkingSet(ctx, headRef, tx.workingSetRef, &pending, workingSet, currHash, tx.getWorkingSetMeta(ctx)) + newCommit, err := doltDb.CommitWithWorkingSet(ctx, headRef, workingSet.Ref(), &pending, workingSet, currHash, tx.getWorkingSetMeta(ctx)) return workingSet, newCommit, err } @@ -303,11 +301,11 @@ func (tx *DoltTransaction) doCommit( newWorkingSet := false - existingWs, err := tx.dbData.Ddb.ResolveWorkingSet(ctx, tx.workingSetRef) + existingWs, err := tx.dbData.Ddb.ResolveWorkingSet(ctx, workingSet.Ref()) if err == doltdb.ErrWorkingSetNotFound { // This is to handle the case where an existing DB pre working sets is committing to this HEAD for the // first time. Can be removed and called an error post 1.0 - existingWs = doltdb.EmptyWorkingSet(tx.workingSetRef) + existingWs = doltdb.EmptyWorkingSet(workingSet.Ref()) newWorkingSet = true } else if err != nil { return nil, nil, err From 0a7c5d72c1a23319a1b0d97f2714e49d2029b489 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 2 May 2023 15:48:28 -0700 Subject: [PATCH 014/167] Killing more old style tx state --- go/libraries/doltcore/sqle/dsess/transactions.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 34ed881a2d..da74322efe 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -74,8 +74,6 @@ func (d DisabledTransaction) IsReadOnly() bool { type DoltTransaction struct { dbStartPoints map[string]dbRoot - startState *doltdb.WorkingSet - dbData env.DbData savepoints []savepoint mergeEditOpts editor.Options tCharacteristic sql.TransactionCharacteristic @@ -103,8 +101,6 @@ func NewDoltTransaction( tCharacteristic sql.TransactionCharacteristic, ) *DoltTransaction { return &DoltTransaction{ - startState: startState, - dbData: dbData, mergeEditOpts: mergeEditOpts, tCharacteristic: tCharacteristic, } @@ -192,7 +188,7 @@ func doltCommit(ctx *sql.Context, } headSpec, _ := doltdb.NewCommitSpec("HEAD") - curHead, err := tx.dbData.Ddb.Resolve(ctx, headSpec, headRef) + curHead, err := doltDb.Resolve(ctx, headSpec, headRef) if err != nil { return nil, nil, err } @@ -301,7 +297,7 @@ func (tx *DoltTransaction) doCommit( newWorkingSet := false - existingWs, err := tx.dbData.Ddb.ResolveWorkingSet(ctx, workingSet.Ref()) + existingWs, err := startPoint.db.ResolveWorkingSet(ctx, workingSet.Ref()) if err == doltdb.ErrWorkingSetNotFound { // This is to handle the case where an existing DB pre working sets is committing to this HEAD for the // first time. Can be removed and called an error post 1.0 From 64db3b5fa9916d93efa5b95282e6acf397d724ff Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 3 May 2023 13:00:32 -0700 Subject: [PATCH 015/167] Killed off merge opts --- go/libraries/doltcore/merge/merge.go | 5 +-- go/libraries/doltcore/sqle/dsess/session.go | 3 +- .../doltcore/sqle/dsess/transactions.go | 35 ++++++++++++++----- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/go/libraries/doltcore/merge/merge.go b/go/libraries/doltcore/merge/merge.go index 794db05949..7cd4eb74ad 100644 --- a/go/libraries/doltcore/merge/merge.go +++ b/go/libraries/doltcore/merge/merge.go @@ -157,10 +157,7 @@ func MergeRoots( tblToStats := make(map[string]*MergeStats) mergedRoot := ourRoot - - optsWithFKChecks := opts - optsWithFKChecks.ForeignKeyChecksDisabled = true - + // Merge tables one at a time. This is done based on name. With table names from ourRoot being merged first, // renaming a table will return delete/modify conflict error consistently. // TODO: merge based on a more durable table identity that persists across renames diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 436f94d0b2..cf08d82b29 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -449,7 +449,8 @@ func (d *DoltSession) DoltCommit( ws, commit, err := dtx.DoltCommit( ctx, workingSet.WithWorkingRoot(commit.Roots.Working).WithStagedRoot(commit.Roots.Staged), - commit) + commit, + dbName) if err != nil { return nil, nil, err } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index da74322efe..04a1be1c2f 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -75,7 +75,6 @@ func (d DisabledTransaction) IsReadOnly() bool { type DoltTransaction struct { dbStartPoints map[string]dbRoot savepoints []savepoint - mergeEditOpts editor.Options tCharacteristic sql.TransactionCharacteristic } @@ -101,7 +100,6 @@ func NewDoltTransaction( tCharacteristic sql.TransactionCharacteristic, ) *DoltTransaction { return &DoltTransaction{ - mergeEditOpts: mergeEditOpts, tCharacteristic: tCharacteristic, } } @@ -169,6 +167,7 @@ type transactionWrite func(ctx *sql.Context, commit *doltdb.PendingCommit, // optional workingSet *doltdb.WorkingSet, // must be provided hash hash.Hash, // hash of the current working set to be written + mergeOps editor.Options, // editor options for merges ) (*doltdb.WorkingSet, *doltdb.Commit, error) // doltCommit is a transactionWrite function that updates the working set and commits a pending commit atomically @@ -179,6 +178,7 @@ func doltCommit(ctx *sql.Context, commit *doltdb.PendingCommit, // optional workingSet *doltdb.WorkingSet, // must be provided currHash hash.Hash, // hash of the current working set to be written + mergeOpts editor.Options, // editor options for merges ) (*doltdb.WorkingSet, *doltdb.Commit, error) { pending := *commit @@ -221,6 +221,7 @@ func doltCommit(ctx *sql.Context, // updates). The merged root value becomes our new Staged root value which // is the value which we are trying to commit. start := time.Now() + result, err := merge.MergeRoots( ctx, pending.Roots.Staged, @@ -228,7 +229,7 @@ func doltCommit(ctx *sql.Context, pending.Roots.Head, curHead, startState, - tx.mergeEditOpts, + mergeOpts, merge.MergeOpts{}) if err != nil { return nil, nil, err @@ -256,6 +257,7 @@ func txCommit(ctx *sql.Context, _ *doltdb.PendingCommit, // optional workingSet *doltdb.WorkingSet, // must be provided hash hash.Hash, // hash of the current working set to be written + _ editor.Options, // editor options for merges ) (*doltdb.WorkingSet, *doltdb.Commit, error) { return workingSet, nil, doltDb.UpdateWorkingSet(ctx, workingSet.Ref(), workingSet, hash, tx.getWorkingSetMeta(ctx)) } @@ -265,8 +267,9 @@ func (tx *DoltTransaction) DoltCommit( ctx *sql.Context, workingSet *doltdb.WorkingSet, commit *doltdb.PendingCommit, + dbName string, ) (*doltdb.WorkingSet, *doltdb.Commit, error) { - return tx.doCommit(ctx, workingSet, commit, doltCommit, "") + return tx.doCommit(ctx, workingSet, commit, doltCommit, dbName) } // doCommit commits this transaction with the write function provided. It takes the same params as DoltCommit @@ -288,6 +291,19 @@ func (tx *DoltTransaction) doCommit( if err != nil { return nil, nil, err } + + // TODO: no-op if the working set hasn't changed since the transaction started + + sess := DSessFromSess(ctx.Session) + dbState, ok, err := sess.LookupDbState(ctx, dbName) + if err != nil { + return nil, nil, err + } + if !ok { + return nil, nil, fmt.Errorf("database %s unknown to transaction, this is a bug", dbName) + } + + mergeOpts := dbState.EditOpts() for i := 0; i < maxTxCommitRetries; i++ { updatedWs, newCommit, err := func() (*doltdb.WorkingSet, *doltdb.Commit, error) { @@ -320,7 +336,7 @@ func (tx *DoltTransaction) doCommit( } var newCommit *doltdb.Commit - workingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, workingSet, existingWSHash) + workingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, workingSet, existingWSHash, mergeOpts) if err == datas.ErrOptimisticLockFailed { // this is effectively a `continue` in the loop return nil, nil, nil @@ -333,7 +349,7 @@ func (tx *DoltTransaction) doCommit( // otherwise (not a ff), merge the working sets together start := time.Now() - mergedWorkingSet, err := tx.mergeRoots(ctx, startState, existingWs, workingSet) + mergedWorkingSet, err := tx.mergeRoots(ctx, startState, existingWs, workingSet, mergeOpts) if err != nil { return nil, nil, err } @@ -345,7 +361,7 @@ func (tx *DoltTransaction) doCommit( } var newCommit *doltdb.Commit - mergedWorkingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, mergedWorkingSet, existingWSHash) + mergedWorkingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, mergedWorkingSet, existingWSHash, mergeOpts) if err == datas.ErrOptimisticLockFailed { // this is effectively a `continue` in the loop return nil, nil, nil @@ -375,6 +391,7 @@ func (tx *DoltTransaction) mergeRoots( startState *doltdb.WorkingSet, existingWorkingSet *doltdb.WorkingSet, workingSet *doltdb.WorkingSet, + mergeOpts editor.Options, ) (*doltdb.WorkingSet, error) { if !rootsEqual(existingWorkingSet.WorkingRoot(), workingSet.WorkingRoot()) { @@ -385,7 +402,7 @@ func (tx *DoltTransaction) mergeRoots( startState.WorkingRoot(), workingSet, startState, - tx.mergeEditOpts, + mergeOpts, merge.MergeOpts{}) if err != nil { return nil, err @@ -401,7 +418,7 @@ func (tx *DoltTransaction) mergeRoots( startState.StagedRoot(), workingSet, startState, - tx.mergeEditOpts, + mergeOpts, merge.MergeOpts{}) if err != nil { return nil, err From 00ca716da2dc90058a27f27555aea6f5f3eac75a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 4 May 2023 15:46:22 -0700 Subject: [PATCH 016/167] Remove unnecessary type case --- go/libraries/doltcore/sqle/dsess/session.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index cf08d82b29..c118763d85 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1533,17 +1533,12 @@ func InitPersistedSystemVars(dEnv *env.DoltEnv) error { // SplitRevisionDbName splits the given database name into its base and revision parts and returns them. Non-revision // DBs use their full name as the base name, and empty string as the revision. func SplitRevisionDbName(db SqlDatabase) (string, string) { - sqldb, ok := db.(SqlDatabase) - if !ok { - return db.Name(), "" - } - dbName := db.Name() - if sqldb.Revision() != "" { - dbName = strings.TrimSuffix(dbName, DbRevisionDelimiter+sqldb.Revision()) + if db.Revision() != "" { + dbName = strings.TrimSuffix(dbName, DbRevisionDelimiter+db.Revision()) } - return dbName, sqldb.Revision() + return dbName, db.Revision() } // TransactionRoot returns the noms root for the given database in the current transaction From bc5c46301d9d6253c6ddec844f61008a0f45dad0 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 4 May 2023 15:57:28 -0700 Subject: [PATCH 017/167] Ripped out validation logic --- go/libraries/doltcore/sqle/dsess/session.go | 25 +-------------------- 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index c118763d85..0d1072660f 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -230,7 +230,7 @@ func (d *DoltSession) Flush(ctx *sql.Context, dbName string) error { // to ValidateSession. This is effectively a way to disable a session. // // Used by sql/cluster logic to make sessions on a server which has -// transitioned roles termainlly error. +// transitioned roles terminally error. func (d *DoltSession) SetValidateErr(err error) { d.validateErr = err } @@ -242,29 +242,6 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { if d.validateErr != nil { return d.validateErr } - sessionState, ok, err := d.lookupDbState(ctx, dbName) - if err != nil { - return err - } - if !ok { - return nil - } - if sessionState.WorkingSet() == nil { - return nil - } - wsRef := sessionState.WorkingSet().Ref() - _, err = sessionState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) - if err == doltdb.ErrWorkingSetNotFound { - _, err = d.newWorkingSetForHead(ctx, wsRef, dbName) - // if the current head is not found, the branch was force deleted, so use nil working set. - if errors.Is(err, doltdb.ErrBranchNotFound) { - return ErrCurrentBranchDeleted - } else if err != nil { - return err - } - } else if err != nil { - return err - } return nil } From 644175eb411bc4ae178cb4a4bcbc97e4a9363cdc Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 4 May 2023 16:12:15 -0700 Subject: [PATCH 018/167] Fixed bug in commit --- go/libraries/doltcore/sqle/dsess/session.go | 6 +++-- .../doltcore/sqle/dsess/transactions.go | 22 +++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 0d1072660f..9df6aeb576 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1032,16 +1032,18 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { DefineSystemVariablesForDB(db.Name()) - var sessionState *DatabaseSessionState branchState := &branchState{} baseName, rev := SplitRevisionDbName(db) - + + DefineSystemVariablesForDB(baseName) + dbState, err := db.InitialDBState(ctx, rev) if err != nil { return err } d.mu.Lock() + var sessionState *DatabaseSessionState if _, ok := d.dbStates[strings.ToLower(baseName)]; !ok { sessionState = NewEmptyDatabaseSessionState() d.dbStates[strings.ToLower(baseName)] = sessionState diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 04a1be1c2f..f25bb73094 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -280,9 +280,18 @@ func (tx *DoltTransaction) doCommit( writeFn transactionWrite, dbName string, ) (*doltdb.WorkingSet, *doltdb.Commit, error) { + sess := DSessFromSess(ctx.Session) + branchState, ok, err := sess.lookupDbState(ctx, dbName) + if err != nil { + return nil, nil, err + } + if !ok { + return nil, nil, fmt.Errorf("database %s unknown to transaction, this is a bug", dbName) + } // Load the start state for this working set from the noms root at tx start - startPoint, ok := tx.dbStartPoints[strings.ToLower(dbName)] + // Get the base DB name from the db state, not the branch state + startPoint, ok := tx.dbStartPoints[strings.ToLower(branchState.dbState.dbName)] if !ok { return nil, nil, fmt.Errorf("database %s unknown to transaction, this is a bug", dbName) } @@ -293,17 +302,8 @@ func (tx *DoltTransaction) doCommit( } // TODO: no-op if the working set hasn't changed since the transaction started - - sess := DSessFromSess(ctx.Session) - dbState, ok, err := sess.LookupDbState(ctx, dbName) - if err != nil { - return nil, nil, err - } - if !ok { - return nil, nil, fmt.Errorf("database %s unknown to transaction, this is a bug", dbName) - } - mergeOpts := dbState.EditOpts() + mergeOpts := branchState.EditOpts() for i := 0; i < maxTxCommitRetries; i++ { updatedWs, newCommit, err := func() (*doltdb.WorkingSet, *doltdb.Commit, error) { From b51ed38de47dbefc66cd31d8e771357ce1cd541d Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 4 May 2023 16:59:41 -0700 Subject: [PATCH 019/167] Couple bug fixes --- go/libraries/doltcore/sqle/dsess/session.go | 18 +-- .../sqle/enginetest/dolt_engine_test.go | 111 +++--------------- 2 files changed, 25 insertions(+), 104 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 9df6aeb576..c90f9b0209 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -176,7 +176,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta } d.mu.Lock() - dbState, ok = d.dbStates[dbName] + dbState, ok = d.dbStates[baseName] d.mu.Unlock() if !ok { return nil, false, sql.ErrDatabaseNotFound.New(dbName) @@ -287,18 +287,12 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, // because they will be re-initialized with the current branch head / working set. -// TODO: this should happen with every dbstate, not just revision DBs. The problem is that we track the current working -// -// set *only* in the session state. We need to disentangle the metadata about a state (working ref, persists across -// transactions) from its data (re-initialized on every transaction start) func (d *DoltSession) clearRevisionDbState() { d.mu.Lock() defer d.mu.Unlock() - for _, dbState := range d.dbStates { - if len(dbState.db.Revision()) > 0 { - delete(d.dbStates, strings.ToLower(dbState.db.Name())) - } + for db := range d.dbStates { + delete(d.dbStates, db) } } @@ -1330,13 +1324,13 @@ func (d *DoltSession) GetBranch() (string, error) { return "", nil } - dbState, _, err := d.LookupDbState(ctx, currentDb) + branchState, _, err := d.LookupDbState(ctx, currentDb) if err != nil { return "", err } - if dbState.WorkingSet() != nil { - branchRef, err := dbState.WorkingSet().Ref().ToHeadRef() + if branchState.WorkingSet() != nil { + branchRef, err := branchState.WorkingSet().Ref().ToHeadRef() if err != nil { return "", err } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 8e81cbc9a3..371c2650a6 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1443,7 +1443,7 @@ func installTestCommitClock(tcc *testCommitClock) func() { // TestSingleTransactionScript is a convenience method for debugging a single transaction test. Unskip and set to the // desired test. func TestSingleTransactionScript(t *testing.T) { - t.Skip() + // t.Skip() tcc := &testCommitClock{} cleanup := installTestCommitClock(tcc) @@ -1452,117 +1452,44 @@ func TestSingleTransactionScript(t *testing.T) { sql.RunWithNowFunc(tcc.Now, func() error { script := queries.TransactionTest{ - Name: "committed conflicts are seen by other sessions", + Name: "autocommit on", SetUpScript: []string{ - "CREATE TABLE test (pk int primary key, val int)", - "CALL DOLT_ADD('.')", - "INSERT INTO test VALUES (0, 0)", - "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", - "CALL DOLT_CHECKOUT('-b', 'feature-branch')", - "INSERT INTO test VALUES (1, 1);", - "UPDATE test SET val=1000 WHERE pk=0;", - "CALL DOLT_COMMIT('-a', '-m', 'this is a normal commit');", - "CALL DOLT_CHECKOUT('main');", - "UPDATE test SET val=1001 WHERE pk=0;", - "CALL DOLT_COMMIT('-a', '-m', 'update a value');", + "create table t (x int primary key, y int)", + "insert into t values (1, 1)", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "/* client a */ start transaction", - Expected: []sql.Row{}, + Query: "/* client a */ insert into t values (2, 2)", + Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, }, { - Query: "/* client b */ start transaction", - Expected: []sql.Row{}, + Query: "/* client b */ select * from t order by x", + Expected: []sql.Row{{1, 1}, {2, 2}}, }, { - Query: "/* client a */ select * from dolt_log order by date", - Expected: - // existing transaction logic - []sql.Row{ - sql.Row{"j131v1r3cf6mrdjjjuqgkv4t33oa0l54", "billy bob", "bigbillieb@fake.horse", time.Date(1969, time.December, 31, 21, 0, 0, 0, time.Local), "Initialize data repository"}, - sql.Row{"kcg4345ir3tjfb13mr0on1bv1m56h9if", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "checkpoint enginetest database mydb"}, - sql.Row{"9jtjpggd4t5nso3mefilbde3tkfosdna", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 1, 12, 0, 0, 0, time.Local), "Step 1"}, - sql.Row{"559f6kdh0mm5i1o40hs3t8dr43bkerav", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 2, 3, 0, 0, 0, time.Local), "update a value"}, - }, - - // new tx logic - // []sql.Row{ - // sql.Row{"j131v1r3cf6mrdjjjuqgkv4t33oa0l54", "billy bob", "bigbillieb@fake.horse", time.Date(1969, time.December, 31, 21, 0, 0, 0, time.Local), "Initialize data repository"}, - // sql.Row{"kcg4345ir3tjfb13mr0on1bv1m56h9if", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "checkpoint enginetest database mydb"}, - // sql.Row{"pifio95ccefa03qstm1g3s1sivj1sm1d", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "Step 1"}, - // sql.Row{"rdrgqfcml1hfgj8clr0caabgu014v2g9", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 1, 20, 0, 0, 0, time.Local), "this is a normal commit"}, - // sql.Row{"shhv61eiefo9c4m9lvo5bt23i3om1ft4", "billy bob", "bigbillieb@fake.horse", time.Date(1970, time.January, 2, 2, 0, 0, 0, time.Local), "update a value"}, - // }, + Query: "/* client b */ insert into t values (3, 3)", + Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, }, { - Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", - Expected: []sql.Row{{0, 1}}, + Query: "/* client b */ select * from t order by x", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, }, { - Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{1}}, + Query: "/* client a */ select * from t order by x", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, }, { - Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{0}}, + Query: "/* client a */ insert into t values (4, 4)", + SkipResultsCheck: true, }, { - Query: "/* client a */ set dolt_allow_commit_conflicts = 1", - Expected: []sql.Row{{}}, - }, - { - Query: "/* client a */ commit", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ start transaction", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{1}}, - }, - { - Query: "/* client a */ start transaction", - Expected: []sql.Row{}, - }, - { - Query: "/* client a */ CALL DOLT_MERGE('--abort')", - Expected: []sql.Row{{0, 0}}, - }, - { - Query: "/* client a */ commit", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ start transaction", - Expected: []sql.Row{}, - }, - { - Query: "/* client a */ SET @@dolt_allow_commit_conflicts = 0", - Expected: []sql.Row{{}}, - }, - { - Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", - ExpectedErrStr: dsess.ErrUnresolvedConflictsCommit.Error(), - }, - { // client rolled back on merge with conflicts - Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{0}}, - }, - { - Query: "/* client a */ commit", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{0}}, + Query: "/* client b */ select * from t order by x", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, }, }, } - h := newDoltHarness(t) + h := newDoltHarness(t) defer h.Close() enginetest.TestTransactionScript(t, h, script) From 33b29cc0b153dcc08b27c27a342c23e31793c16d Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 4 May 2023 17:22:21 -0700 Subject: [PATCH 020/167] Biting the bullet on switch working set --- go/libraries/doltcore/sqle/dsess/session.go | 88 +------------------ .../doltcore/sqle/dsess/transactions.go | 16 ---- 2 files changed, 3 insertions(+), 101 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index c90f9b0209..a091639750 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -825,94 +825,12 @@ func (d *DoltSession) SwitchWorkingSet( dbName string, wsRef ref.WorkingSetRef, ) error { - branchState, _, err := d.lookupDbState(ctx, dbName) + headRef, err := wsRef.ToHeadRef() if err != nil { return err } - - // TODO: should this be an error if any database in the transaction is dirty, or just this one? - if branchState.dbState.dirty { - return ErrWorkingSetChanges.New() - } - - // TODO: this should call session.StartTransaction once that has been cleaned up a bit - nomsRoots := make(map[string]hash.Hash) - for _, db := range d.provider.DoltDatabases() { - nomsRoot, err := db.DbData().Ddb.NomsRoot(ctx) - if err != nil { - return err - } - nomsRoots[strings.ToLower(db.Name())] = nomsRoot - } - - // TODO: resolve the working set ref with the root above - ws, err := branchState.dbData.Ddb.ResolveWorkingSet(ctx, wsRef) - if err != nil { - return err - } - - // TODO: just call SetWorkingSet? - branchState.workingSet = ws - - cs, err := doltdb.NewCommitSpec(ws.Ref().GetPath()) - if err != nil { - return err - } - - branchRef, err := ws.Ref().ToHeadRef() - if err != nil { - return err - } - - cm, err := branchState.dbData.Ddb.Resolve(ctx, cs, branchRef) - if err != nil { - return err - } - - branchState.headCommit = cm - branchState.headRoot, err = cm.GetRootValue(ctx) - if err != nil { - return err - } - - err = d.setSessionVarsForDb(ctx, dbName) - if err != nil { - return err - } - - h, err := ws.WorkingRoot().HashOf() - if err != nil { - return err - } - - err = d.Session.SetSessionVariable(ctx, WorkingKey(dbName), h.String()) - if err != nil { - return err - } - - // make a fresh WriteSession, discard existing WriteSession - opts := branchState.WriteSession().GetOptions() - nbf := ws.WorkingRoot().VRW().Format() - tracker, err := branchState.dbState.globalState.GetAutoIncrementTracker(ctx) - if err != nil { - return err - } - branchState.writeSession = writer.NewWriteSession(nbf, ws, tracker, opts) - - // After switching to a new working set, we are by definition clean - // TODO: obviously this is no longer true but this entire method needs a rewrite to tolerate writing to multiple - // heads in one tx - branchState.dbState.dirty = false - - // the current transaction, if there is one, needs to be restarted - tCharacteristic := sql.ReadWrite - if t := ctx.GetTransaction(); t != nil { - if t.IsReadOnly() { - tCharacteristic = sql.ReadOnly - } - } - ctx.SetTransaction(NewDoltTransaction(nomsRoots, ws, wsRef, branchState.dbData, branchState.WriteSession().GetOptions(), tCharacteristic)) - + + ctx.SetCurrentDatabase(dbName + DbRevisionDelimiter + headRef.GetPath()) return nil } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index f25bb73094..be457d5e41 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -25,9 +25,7 @@ import ( "github.com/sirupsen/logrus" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" - "github.com/dolthub/dolt/go/libraries/doltcore/env" "github.com/dolthub/dolt/go/libraries/doltcore/merge" - "github.com/dolthub/dolt/go/libraries/doltcore/ref" "github.com/dolthub/dolt/go/libraries/doltcore/table/editor" "github.com/dolthub/dolt/go/store/datas" "github.com/dolthub/dolt/go/store/hash" @@ -90,20 +88,6 @@ type savepoint struct { root *doltdb.RootValue } -// TODO: find refs to this and remove -func NewDoltTransaction( - startingRoots map[string]hash.Hash, - startState *doltdb.WorkingSet, - workingSet ref.WorkingSetRef, - dbData env.DbData, - mergeEditOpts editor.Options, - tCharacteristic sql.TransactionCharacteristic, -) *DoltTransaction { - return &DoltTransaction{ - tCharacteristic: tCharacteristic, - } -} - func NewMultiHeadTransaction( ctx *sql.Context, dbs []SqlDatabase, From ca68a2e1a0d2db20b308e8ac5a66752d8786880f Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 4 May 2023 18:36:56 -0700 Subject: [PATCH 021/167] Re-instate the dirty check --- go/libraries/doltcore/sqle/dsess/session.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index a091639750..1839e1ed71 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -331,7 +331,7 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er if isNoOpTransactionDatabase(dbName) { return nil } - + if d.BatchMode() == Batched { err := d.Flush(ctx, dbName) if err != nil { @@ -343,6 +343,15 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er return nil } + isDirty, err := d.isDirty(ctx, dbName) + if err != nil { + return err + } + + if !isDirty { + return nil + } + // This is triggered when certain commands are sent to the server (ex. commit) when a database is not selected. // These commands should not error. if dbName == "" { From 8d52bb9b7b6301876bbc6b9b8b6697f5c6d84d93 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 5 May 2023 07:28:36 -0700 Subject: [PATCH 022/167] checkpoint --- .../doltcore/sqle/database_provider.go | 22 +++++++++---------- go/libraries/doltcore/sqle/dsess/session.go | 4 ++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 2074254aca..36ceef35a7 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -291,17 +291,17 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database p.mu.RUnlock() // If the current database is not one of the primary databases, it must be a transitory revision database - if !foundDatabase && currDb != "" { - revDb, ok, err := p.databaseForRevision(ctx, currDb) - if err != nil { - // We can't return an error from this interface function, so just log a message - ctx.GetLogger().Warnf("unable to load %q as a database revision: %s", ctx.GetCurrentDatabase(), err.Error()) - } else if !ok { - ctx.GetLogger().Warnf("unable to load %q as a database revision", ctx.GetCurrentDatabase()) - } else { - all = append(all, revDb) - } - } + // if !foundDatabase && currDb != "" { + // revDb, ok, err := p.databaseForRevision(ctx, currDb) + // if err != nil { + // // We can't return an error from this interface function, so just log a message + // ctx.GetLogger().Warnf("unable to load %q as a database revision: %s", ctx.GetCurrentDatabase(), err.Error()) + // } else if !ok { + // ctx.GetLogger().Warnf("unable to load %q as a database revision", ctx.GetCurrentDatabase()) + // } else { + // all = append(all, revDb) + // } + // } // Because we store databases in a map, sort to get a consistent ordering sort.Slice(all, func(i, j int) bool { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 1839e1ed71..b6a6f262b1 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -192,6 +192,10 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta // the checked out branch in the case of a default (no branch-specified) db connection. // Alternate idea: branch head is always set correctly in response to a USE statement, OR a checkout procedure. The // latter implicitly updates the current database. You also get a revision db checked out on connection to no branch. +// The original idea is more tractable for now -- too many things break with the latter approach, although it's cleaner +// in many respects. Biggest blocker is grants, which are currently tied to the base database name and probably need to +// stay that way. Unless I can come up with some clever workaround... +// Possible workaround for permissions: new GMS interface for "permissionDbName" or similar, workable? func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (SessionState, bool, error) { s, ok, err := d.lookupDbState(ctx, dbName) if err != nil { From 7333e5acdcf0745510bb64483f136024984ce8f7 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 5 May 2023 12:36:49 -0700 Subject: [PATCH 023/167] Starting down the path of all db having a base name only independent of their revision --- go/libraries/doltcore/sqle/database.go | 5 +- .../doltcore/sqle/database_provider.go | 24 ++++----- go/libraries/doltcore/sqle/dsess/session.go | 50 +++++++++++++++++-- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 97e6e60a77..f49d58f1df 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -99,9 +99,9 @@ func (db Database) RevisionType() dsess.RevisionType { return db.revType } +// TODO: remove this func (db Database) BaseName() string { - base, _ := dsess.SplitRevisionDbName(db) - return base + return db.name } func (db Database) EditOptions() editor.Options { @@ -132,6 +132,7 @@ func initialDBState(ctx *sql.Context, db dsess.SqlDatabase, branch string) (dses return initialStateForRevisionDb(ctx, db) } + // TODO: this should never be true return initialDbState(ctx, db, branch) } diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 36ceef35a7..4a76e1e62f 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -734,10 +734,10 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string } parts := strings.SplitN(revDB, dsess.DbRevisionDelimiter, 2) - dbName, revSpec := parts[0], parts[1] + baseName, rev := parts[0], parts[1] p.mu.RLock() - candidate, ok := p.databases[formatDbMapKeyName(dbName)] + candidate, ok := p.databases[formatDbMapKeyName(baseName)] p.mu.RUnlock() if !ok { return nil, false, nil @@ -748,7 +748,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string return nil, false, nil } - dbType, resolvedRevSpec, err := revisionDbType(ctx, srcDb, revSpec) + dbType, resolvedRevSpec, err := revisionDbType(ctx, srcDb, rev) if err != nil { return nil, false, err } @@ -803,7 +803,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string if !ok { return nil, false, nil } - db, err := revisionDbForCommit(ctx, srcDb.(Database), revSpec) + db, err := revisionDbForCommit(ctx, srcDb.(Database), rev) if err != nil { return nil, false, err } @@ -812,7 +812,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string // not an error, ok = false will get handled as a not found error in a layer above as appropriate return nil, false, nil default: - return nil, false, fmt.Errorf("unrecognized revision type for revision spec %s", revSpec) + return nil, false, fmt.Errorf("unrecognized revision type for revision spec %s", rev) } } @@ -1073,7 +1073,8 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds // The db map only contains base databases, not revision DBs. Convert to a revision DB for creation. if !isRevisionDb { - // TODO: capture the initial checked out head at startup, don't get it here every time + // TODO: capture the initial checked out head at startup, don't get it here every time + // TODO: shouldn't use CWBHeadRef here, should come from the session's working set headRef := db.DbData().Rsr.CWBHeadRef() name = baseName + dsess.DbRevisionDelimiter + headRef.GetPath() } @@ -1250,7 +1251,6 @@ func isTag(ctx context.Context, db dsess.SqlDatabase, tagName string) (bool, err // revisionDbForBranch returns a new database that is tied to the branch named by revSpec func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec string) (dsess.SqlDatabase, error) { branch := ref.NewBranchRef(revSpec) - dbName := srcDb.Name() + dsess.DbRevisionDelimiter + revSpec static := staticRepoState{ branch: branch, @@ -1263,7 +1263,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s switch v := srcDb.(type) { case Database: db = Database{ - name: dbName, + name: srcDb.Name(), ddb: v.ddb, rsw: static, rsr: static, @@ -1275,7 +1275,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s case ReadReplicaDatabase: db = ReadReplicaDatabase{ Database: Database{ - name: dbName, + name: srcDb.Name(), ddb: v.ddb, rsw: static, rsr: static, @@ -1359,9 +1359,8 @@ func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.I } func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string) (ReadOnlyDatabase, error) { - name := srcDb.Name() + dsess.DbRevisionDelimiter + revSpec db := ReadOnlyDatabase{Database: Database{ - name: name, + name: srcDb.Name(), ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, rsr: srcDb.DbData().Rsr, @@ -1402,9 +1401,8 @@ func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.In } func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string) (ReadOnlyDatabase, error) { - name := srcDb.Name() + dsess.DbRevisionDelimiter + revSpec db := ReadOnlyDatabase{Database: Database{ - name: name, + name: srcDb.Name(), ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, rsr: srcDb.DbData().Rsr, diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index b6a6f262b1..8d42958611 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -22,7 +22,7 @@ import ( "strings" "sync" "time" - + "github.com/dolthub/go-mysql-server/sql" sqltypes "github.com/dolthub/go-mysql-server/sql/types" goerrors "gopkg.in/src-d/go-errors.v1" @@ -137,18 +137,30 @@ func DSessFromSess(sess sql.Session) *DoltSession { // lookupDbState is the private version of LookupDbState, returning a struct that has more information available than // the interface returned by the public method. func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchState, bool, error) { - // TODO: change to require a db, not a name so that the below doesn't need to do a string split dbName = strings.ToLower(dbName) + var baseName, rev string parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) - baseName := parts[0] + baseName = parts[0] + if len(parts) > 1 { + rev = parts[1] + } d.mu.Lock() dbState, ok := d.dbStates[baseName] d.mu.Unlock() if ok { - _, rev := SplitRevisionDbName(dbState.db) + // If we got an unqualified name, use the current working set head + if rev == "" { + headRef, err := dbState.currentHead.ToHeadRef() + if err != nil { + return nil, false, err + } + + rev = headRef.GetPath() + } + branchState, ok := dbState.heads[strings.ToLower(rev)] if ok { @@ -182,7 +194,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta return nil, false, sql.ErrDatabaseNotFound.New(dbName) } - _, rev := SplitRevisionDbName(database) + _, rev = SplitRevisionDbName(database) return dbState.heads[strings.ToLower(rev)], true, nil } @@ -205,6 +217,32 @@ func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (SessionSta return s, ok, nil } +// func (d *DoltSession) CurrentDbState(ctx *sql.Context) (SessionState, bool, error) { +// db := ctx.GetCurrentDatabase() +// if db == "" { +// return nil, false, fmt.Errorf("no current database") +// } +// +// // TODO: this should always be false, right? +// isRevisionDb := strings.Contains(db, DbRevisionDelimiter) +// if !isRevisionDb { +// d.mu.Lock() +// dbState, ok := d.dbStates[strings.ToLower(db)] +// d.mu.Unlock() +// +// if !ok { +// return d.lookupDbState(ctx, db) +// } +// } +// +// s, ok, err := d.lookupDbState(ctx, db) +// if err != nil { +// return nil, false, err +// } +// +// return s, ok, nil +// } + // RemoveDbState invalidates any cached db state in this session, for example, if a database is dropped. func (d *DoltSession) RemoveDbState(_ *sql.Context, dbName string) error { d.mu.Lock() @@ -955,6 +993,7 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { // addDB adds the database given to this session. This establishes a starting root value for this session, as well as // other state tracking metadata. func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { + // TODO: get rid of this, only define these for base names DefineSystemVariablesForDB(db.Name()) branchState := &branchState{} @@ -1436,6 +1475,7 @@ func InitPersistedSystemVars(dEnv *env.DoltEnv) error { // SplitRevisionDbName splits the given database name into its base and revision parts and returns them. Non-revision // DBs use their full name as the base name, and empty string as the revision. +// TODO: get rid of this, should no longer be necessary func SplitRevisionDbName(db SqlDatabase) (string, string) { dbName := db.Name() if db.Revision() != "" { From 62148bbba7a1f4da88cba012fc146ba95a333b87 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 5 May 2023 13:29:06 -0700 Subject: [PATCH 024/167] better definition for current rev on dbstate --- .../sqle/dsess/database_session_state.go | 9 ++-- go/libraries/doltcore/sqle/dsess/session.go | 44 +++++++++++++------ .../sqle/dsess/session_db_provider.go | 1 + 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index ce27dedad5..d0d2843149 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -15,7 +15,6 @@ package dsess import ( - "github.com/dolthub/dolt/go/libraries/doltcore/ref" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" @@ -63,8 +62,12 @@ type DatabaseSessionState struct { dbName string // db is the database this state applies to db SqlDatabase - // currentHead is the current head of the database when unqualified by a DB name - currentHead ref.WorkingSetRef + // currRevSpec is the current revision spec of the database when referred to by its base name. Changes when a + // `dolt_checkout` or `use` statement is executed. + currRevSpec string + // currRevType is the current revision type of the database when referred to by its base name. Changes when a + // `dolt_checkout` or `use` statement is executed. + currRevType RevisionType // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState // globalState is the global state of this session (shared by all sessions for a particular db) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 8d42958611..db5665b1cc 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -140,11 +140,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta dbName = strings.ToLower(dbName) var baseName, rev string - parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) - baseName = parts[0] - if len(parts) > 1 { - rev = parts[1] - } + baseName, rev = splitDbName(dbName) d.mu.Lock() dbState, ok := d.dbStates[baseName] @@ -153,14 +149,9 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta if ok { // If we got an unqualified name, use the current working set head if rev == "" { - headRef, err := dbState.currentHead.ToHeadRef() - if err != nil { - return nil, false, err - } - - rev = headRef.GetPath() + rev = dbState.currRevSpec } - + branchState, ok := dbState.heads[strings.ToLower(rev)] if ok { @@ -171,7 +162,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta return branchState, ok, nil } } - + // no state for this db / branch combination yet, look it up from the provider database, ok, err := d.provider.SessionDatabase(ctx, dbName) if err != nil { @@ -198,6 +189,16 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta return dbState.heads[strings.ToLower(rev)], true, nil } +func splitDbName(dbName string) (string, string) { + var baseName, rev string + parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) + baseName = parts[0] + if len(parts) > 1 { + rev = parts[1] + } + return baseName, rev +} + // TODO NEXT: the lookupdbstate method is the key abstraction point. It proxies all non-revisoined DBs to a revisioned // state, based on the current db (the default branch if none). The session stores all data by working set ref. DB // names are masked on return in the case of a non-revisined DB. Session stae is also responsible for keeping track of @@ -880,8 +881,18 @@ func (d *DoltSession) SwitchWorkingSet( if err != nil { return err } + + d.mu.Lock() + defer d.mu.Unlock() + + baseName, _ := splitDbName(dbName) + dbState, ok := d.dbStates[strings.ToLower(baseName)] + if !ok { + return sql.ErrDatabaseNotFound.New(dbName) + } + dbState.currRevSpec = headRef.GetPath() + dbState.currRevType = RevisionTypeBranch - ctx.SetCurrentDatabase(dbName + DbRevisionDelimiter + headRef.GetPath()) return nil } @@ -1020,7 +1031,12 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { return err } sessionState.tmpFileDir = tmpDir + + // TODO: is this right? + sessionState.currRevSpec = db.Revision() + sessionState.currRevType = db.RevisionType() } + branchState.dbState = sessionState sessionState.heads[strings.ToLower(rev)] = branchState d.mu.Unlock() diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index 7aa947dc59..e3c46c16cd 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -47,6 +47,7 @@ type RevisionDatabase interface { // string naming that branch or tag. For other revision specs, e.g. "HEAD~2", the revision is a commit hash. type RevisionType int +// TODO: do we need a working set type here, or no? const ( RevisionTypeNone RevisionType = iota RevisionTypeBranch From fcd4d65f91619e85f46350443aa88991029d41bd Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 8 May 2023 11:14:33 -0700 Subject: [PATCH 025/167] dolt_checkout(-b) needs a new transaction --- .../sqle/dprocedures/dolt_checkout.go | 21 +++-- go/libraries/doltcore/sqle/dsess/session.go | 82 +++++++++-------- .../sqle/enginetest/dolt_engine_test.go | 89 +++++++++++++++---- .../sqle/writer/noms_write_session.go | 1 + 4 files changed, 134 insertions(+), 59 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index 21ef428198..96758b3389 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -263,11 +263,7 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * if err != nil { return err } - err = checkoutBranch(ctx, dbName, newBranchName) - if err != nil { - return err - } - + if setTrackUpstream { err = env.SetRemoteUpstreamForRefSpec(dbData.Rsw, refSpec, remoteName, ref.NewBranchRef(remoteBranchName)) if err != nil { @@ -284,8 +280,21 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * return err } } + + // We need to commit the transaction here or else the branch we just created isn't visible to the current transaction, + // and we are about to switch to it. So set the new branch head for the new transaction, then commit this one + sess := dsess.DSessFromSess(ctx.Session) + err = commitTransaction(ctx, sess) + if err != nil { + return err + } - return nil + wsRef, err := ref.WorkingSetRefForHead(ref.NewBranchRef(newBranchName)) + if err != nil { + return err + } + + return sess.SetCurrentHead(ctx, dbName, wsRef) } func checkoutBranch(ctx *sql.Context, dbName string, branchName string) error { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index db5665b1cc..5ac55880f2 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -816,6 +816,7 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo // SetWorkingSet sets the working set for this session. // Unlike setting the working root alone, this method always marks the session dirty. +// TODO: this is doing a lot of resolve work that should only happen once, at initialization time func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb.WorkingSet) error { if ws == nil { panic("attempted to set a nil working set for the session") @@ -830,33 +831,12 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. } branchState.workingSet = ws - cs, err := doltdb.NewCommitSpec(ws.Ref().GetPath()) - if err != nil { - return err - } - - branchRef, err := ws.Ref().ToHeadRef() - if err != nil { - return err - } - - cm, err := branchState.dbData.Ddb.Resolve(ctx, cs, branchRef) - if err != nil { - return err - } - branchState.headCommit = cm - - headRoot, err := cm.GetRootValue(ctx) - if err != nil { - return err - } - branchState.headRoot = headRoot - err = d.setSessionVarsForDb(ctx, dbName) if err != nil { return err } + // TODO: remove this err = branchState.WriteSession().SetWorkingSet(ctx, ws) if err != nil { return err @@ -867,6 +847,30 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return nil } +// SetCurrentHead sets the currently connected head revision spec for this session. +// TODO: more caveats and guidance +func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref.WorkingSetRef) error { + headRef, err := wsRef.ToHeadRef() + if err != nil { + return err + } + + d.mu.Lock() + + baseName, _ := splitDbName(dbName) + dbState, ok := d.dbStates[strings.ToLower(baseName)] + if !ok { + d.mu.Unlock() + return sql.ErrDatabaseNotFound.New(dbName) + } + dbState.currRevSpec = headRef.GetPath() + dbState.currRevType = RevisionTypeBranch + + d.mu.Unlock() + + return nil +} + // SwitchWorkingSet switches to a new working set for this session. Unlike SetWorkingSet, this method expresses no // intention to eventually persist any uncommitted changes. Rather, this method only changes the in memory state of // this session. It's equivalent to starting a new session with the working set reference provided. If the current @@ -883,15 +887,27 @@ func (d *DoltSession) SwitchWorkingSet( } d.mu.Lock() - defer d.mu.Unlock() baseName, _ := splitDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { + d.mu.Unlock() return sql.ErrDatabaseNotFound.New(dbName) } dbState.currRevSpec = headRef.GetPath() dbState.currRevType = RevisionTypeBranch + + d.mu.Unlock() + + // bootstrap the db state as necessary + _, ok, err = d.lookupDbState(ctx, baseName + DbRevisionDelimiter + headRef.GetPath()) + if err != nil { + return err + } + + if !ok { + return sql.ErrDatabaseNotFound.New(dbName) + } return nil } @@ -1018,8 +1034,8 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } d.mu.Lock() - var sessionState *DatabaseSessionState - if _, ok := d.dbStates[strings.ToLower(baseName)]; !ok { + sessionState, ok := d.dbStates[strings.ToLower(baseName)] + if !ok { sessionState = NewEmptyDatabaseSessionState() d.dbStates[strings.ToLower(baseName)] = sessionState @@ -1081,11 +1097,10 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { return err } branchState.writeSession = writer.NewWriteSession(nbf, branchState.WorkingSet(), tracker, editOpts) - if err = d.SetWorkingSet(ctx, db.Name(), dbState.WorkingSet); err != nil { - return err - } - } else if dbState.HeadCommit != nil { - // WorkingSet is nil in the case of a read only, detached head DB + } + + // WorkingSet is nil in the case of a read only, detached head DB + if dbState.HeadCommit != nil { headRoot, err := dbState.HeadCommit.GetRootValue(ctx) if err != nil { return err @@ -1098,14 +1113,11 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { // This has to happen after SetWorkingSet above, since it does a stale check before its work // TODO: this needs to be kept up to date as the working set ref changes branchState.headCommit = dbState.HeadCommit - - // After setting the initial root we have no state to commit - // TODO: do we still want to track dirty states, or just look at hashes - sessionState.dirty = false - + if sessionState.Err == nil { return d.setSessionVarsForDb(ctx, db.Name()) } + return nil } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 371c2650a6..57fd14b758 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1452,44 +1452,97 @@ func TestSingleTransactionScript(t *testing.T) { sql.RunWithNowFunc(tcc.Now, func() error { script := queries.TransactionTest{ - Name: "autocommit on", + Name: "committed conflicts are seen by other sessions", SetUpScript: []string{ - "create table t (x int primary key, y int)", - "insert into t values (1, 1)", + "CREATE TABLE test (pk int primary key, val int)", + "CALL DOLT_ADD('.')", + "INSERT INTO test VALUES (0, 0)", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", + "CALL DOLT_CHECKOUT('-b', 'feature-branch')", + "INSERT INTO test VALUES (1, 1);", + "UPDATE test SET val=1000 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'this is a normal commit');", + "CALL DOLT_CHECKOUT('main');", + "UPDATE test SET val=1001 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'update a value');", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "/* client a */ insert into t values (2, 2)", - Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, + Query: "/* client a */ start transaction", + Expected: []sql.Row{}, }, { - Query: "/* client b */ select * from t order by x", - Expected: []sql.Row{{1, 1}, {2, 2}}, + Query: "/* client b */ start transaction", + Expected: []sql.Row{}, }, { - Query: "/* client b */ insert into t values (3, 3)", - Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, + Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", + Expected: []sql.Row{{0, 1}}, }, { - Query: "/* client b */ select * from t order by x", - Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", + Expected: []sql.Row{{1}}, }, { - Query: "/* client a */ select * from t order by x", - Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", + Expected: []sql.Row{{0}}, }, { - Query: "/* client a */ insert into t values (4, 4)", - SkipResultsCheck: true, + Query: "/* client a */ set dolt_allow_commit_conflicts = 1", + Expected: []sql.Row{{}}, }, { - Query: "/* client b */ select * from t order by x", - Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, + Query: "/* client a */ commit", + Expected: []sql.Row{}, + }, + { + Query: "/* client b */ start transaction", + Expected: []sql.Row{}, + }, + { + Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", + Expected: []sql.Row{{1}}, + }, + { + Query: "/* client a */ start transaction", + Expected: []sql.Row{}, + }, + { + Query: "/* client a */ CALL DOLT_MERGE('--abort')", + Expected: []sql.Row{{0, 0}}, + }, + { + Query: "/* client a */ commit", + Expected: []sql.Row{}, + }, + { + Query: "/* client b */ start transaction", + Expected: []sql.Row{}, + }, + { + Query: "/* client a */ SET @@dolt_allow_commit_conflicts = 0", + Expected: []sql.Row{{}}, + }, + { + Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", + ExpectedErrStr: dsess.ErrUnresolvedConflictsCommit.Error(), + }, + { // client rolled back on merge with conflicts + Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", + Expected: []sql.Row{{0}}, + }, + { + Query: "/* client a */ commit", + Expected: []sql.Row{}, + }, + { + Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", + Expected: []sql.Row{{0}}, }, }, } - h := newDoltHarness(t) + h := newDoltHarness(t) defer h.Close() enginetest.TestTransactionScript(t, h, script) diff --git a/go/libraries/doltcore/sqle/writer/noms_write_session.go b/go/libraries/doltcore/sqle/writer/noms_write_session.go index d8afada9b9..763d29fd66 100644 --- a/go/libraries/doltcore/sqle/writer/noms_write_session.go +++ b/go/libraries/doltcore/sqle/writer/noms_write_session.go @@ -37,6 +37,7 @@ type WriteSession interface { GetTableWriter(ctx context.Context, table, db string, setter SessionRootSetter, batched bool) (TableWriter, error) // SetWorkingSet modifies the state of the WriteSession. The WorkingSetRef of |ws| must match the existing Ref. + // TODO: kill this, do not reuse write sessions between working sets SetWorkingSet(ctx context.Context, ws *doltdb.WorkingSet) error // GetOptions returns the editor.Options for this session. From 6ff29492e1ab3d6f3db0c09c67e31864697d51ec Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 8 May 2023 13:52:39 -0700 Subject: [PATCH 026/167] Fixing more initialization bugs --- .../sqle/dprocedures/dolt_checkout.go | 11 +- go/libraries/doltcore/sqle/dsess/session.go | 22 +- .../doltcore/sqle/enginetest/dolt_queries.go | 352 +++++++++--------- 3 files changed, 198 insertions(+), 187 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index 96758b3389..32769ad037 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -272,12 +272,11 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * } else if autoSetupMerge, err := loadConfig(ctx).GetString("branch.autosetupmerge"); err != nil || autoSetupMerge != "false" { remoteName, remoteBranchName = actions.ParseRemoteBranchName(startPt) refSpec, err = ref.ParseRefSpecForRemote(remoteName, remoteBranchName) - if err != nil { - return nil - } - err = env.SetRemoteUpstreamForRefSpec(dbData.Rsw, refSpec, remoteName, ref.NewBranchRef(remoteBranchName)) - if err != nil { - return err + if err == nil { + err = env.SetRemoteUpstreamForRefSpec(dbData.Rsw, refSpec, remoteName, ref.NewBranchRef(remoteBranchName)) + if err != nil { + return err + } } } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 5ac55880f2..31e46815f3 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -163,8 +163,15 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta } } - // no state for this db / branch combination yet, look it up from the provider - database, ok, err := d.provider.SessionDatabase(ctx, dbName) + // No state for this db / branch combination yet, look it up from the provider. We use the unqualified DB name (no + // branch) if the current DB has not yet been loaded into this session. It will resolve to that DB's default branch + // in that case. + sessionDbName := dbName + if rev != "" { + sessionDbName = revisionDbName(baseName, rev) + } + + database, ok, err := d.provider.SessionDatabase(ctx, sessionDbName) if err != nil { return nil, false, err } @@ -189,6 +196,10 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta return dbState.heads[strings.ToLower(rev)], true, nil } +func revisionDbName(baseName string, rev string) string { + return baseName + DbRevisionDelimiter + rev +} + func splitDbName(dbName string) (string, string) { var baseName, rev string parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) @@ -334,8 +345,10 @@ func (d *DoltSession) clearRevisionDbState() { d.mu.Lock() defer d.mu.Unlock() - for db := range d.dbStates { - delete(d.dbStates, db) + for _, dbState := range d.dbStates { + for head := range dbState.heads { + delete(dbState.heads, head) + } } } @@ -1314,6 +1327,7 @@ func (d *DoltSession) SystemVariablesInConfig() ([]sql.SystemVariable, error) { // GetBranch implements the interface branch_control.Context. func (d *DoltSession) GetBranch() (string, error) { + // TODO: creating a new SQL context here is expensive ctx := sql.NewContext(context.Background(), sql.WithSession(d)) currentDb := d.Session.GetCurrentDatabase() diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 025cf007a9..4891bbdf00 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -23,8 +23,6 @@ import ( "github.com/dolthub/go-mysql-server/sql/expression" "github.com/dolthub/go-mysql-server/sql/plan" "github.com/dolthub/go-mysql-server/sql/types" - - "github.com/dolthub/dolt/go/libraries/doltcore/sqle" ) var ViewsWithAsOfScriptTest = queries.ScriptTest{ @@ -2171,181 +2169,181 @@ var DoltGC = []queries.ScriptTest{ } var LogTableFunctionScriptTests = []queries.ScriptTest{ - { - Name: "invalid arguments", - SetUpScript: []string{ - "create table t (pk int primary key, c1 varchar(20), c2 varchar(20));", - "call dolt_add('.')", - "set @Commit1 = '';", - "call dolt_commit_hash_out(@Commit1, '-am', 'creating table t');", - - "insert into t values(1, 'one', 'two'), (2, 'two', 'three');", - "set @Commit2 = '';", - "call dolt_commit_hash_out(@Commit2, '-am', 'inserting into t');", - }, - Assertions: []queries.ScriptTestAssertion{ - { - Query: "SELECT * from dolt_log(@Commit1, @Commit2, 't');", - ExpectedErr: sql.ErrInvalidArgumentNumber, - }, - { - Query: "SELECT * from dolt_log(null);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(null, null);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(null, '--not', null);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, '--not', null);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, '--min-parents', null);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, '--min-parents', 123);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(123, @Commit1);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, 123);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, '--not', 123);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('main..branch1', @Commit1);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('^main..branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('^main...branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, 'main..branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, 'main...branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('main..branch1', '--not', @Commit1);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('main...branch1', '--not', @Commit1);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('^main', '--not', @Commit1);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('main', '--not', '^branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('main', '--not', 'main..branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('^main', @Commit2, '--not', @Commit1);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log(@Commit1, @Commit2);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('^main', '^branch1');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('^main');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('fake-branch');", - ExpectedErrStr: "branch not found: fake-branch", - }, - { - Query: "SELECT * from dolt_log('^fake-branch', 'main');", - ExpectedErrStr: "branch not found: fake-branch", - }, - { - Query: "SELECT * from dolt_log('fake-branch', '^main');", - ExpectedErrStr: "branch not found: fake-branch", - }, - { - Query: "SELECT * from dolt_log('main..fake-branch');", - ExpectedErrStr: "branch not found: fake-branch", - }, - { - Query: "SELECT * from dolt_log('main', '--not', 'fake-branch');", - ExpectedErrStr: "branch not found: fake-branch", - }, - { - Query: "SELECT * from dolt_log(concat('fake', '-', 'branch'));", - ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - }, - { - Query: "SELECT * from dolt_log(hashof('main'));", - ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - }, - { - Query: "SELECT * from dolt_log(@Commit3, '--not', hashof('main'));", - ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - }, - { - Query: "SELECT * from dolt_log(@Commit1, LOWER(@Commit2));", - ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - }, - { - Query: "SELECT parents from dolt_log();", - ExpectedErrStr: `column "parents" could not be found in any table in scope`, - }, - { - Query: "SELECT * from dolt_log('--decorate', 'invalid');", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('--decorate', 123);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT * from dolt_log('--decorate', null);", - ExpectedErr: sql.ErrInvalidArgumentDetails, - }, - { - Query: "SELECT refs from dolt_log();", - ExpectedErrStr: `column "refs" could not be found in any table in scope`, - }, - { - Query: "SELECT refs from dolt_log('--decorate', 'auto');", - ExpectedErrStr: `column "refs" could not be found in any table in scope`, - }, - { - Query: "SELECT refs from dolt_log('--decorate', 'no');", - ExpectedErrStr: `column "refs" could not be found in any table in scope`, - }, - }, - }, + // { + // Name: "invalid arguments", + // SetUpScript: []string{ + // "create table t (pk int primary key, c1 varchar(20), c2 varchar(20));", + // "call dolt_add('.')", + // "set @Commit1 = '';", + // "call dolt_commit_hash_out(@Commit1, '-am', 'creating table t');", + // + // "insert into t values(1, 'one', 'two'), (2, 'two', 'three');", + // "set @Commit2 = '';", + // "call dolt_commit_hash_out(@Commit2, '-am', 'inserting into t');", + // }, + // Assertions: []queries.ScriptTestAssertion{ + // { + // Query: "SELECT * from dolt_log(@Commit1, @Commit2, 't');", + // ExpectedErr: sql.ErrInvalidArgumentNumber, + // }, + // { + // Query: "SELECT * from dolt_log(null);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(null, null);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(null, '--not', null);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, '--not', null);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, '--min-parents', null);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, '--min-parents', 123);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(123, @Commit1);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, 123);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, '--not', 123);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('main..branch1', @Commit1);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('^main..branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('^main...branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, 'main..branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, 'main...branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('main..branch1', '--not', @Commit1);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('main...branch1', '--not', @Commit1);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('^main', '--not', @Commit1);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('main', '--not', '^branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('main', '--not', 'main..branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('^main', @Commit2, '--not', @Commit1);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, @Commit2);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('^main', '^branch1');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('^main');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('fake-branch');", + // ExpectedErrStr: "branch not found: fake-branch", + // }, + // { + // Query: "SELECT * from dolt_log('^fake-branch', 'main');", + // ExpectedErrStr: "branch not found: fake-branch", + // }, + // { + // Query: "SELECT * from dolt_log('fake-branch', '^main');", + // ExpectedErrStr: "branch not found: fake-branch", + // }, + // { + // Query: "SELECT * from dolt_log('main..fake-branch');", + // ExpectedErrStr: "branch not found: fake-branch", + // }, + // { + // Query: "SELECT * from dolt_log('main', '--not', 'fake-branch');", + // ExpectedErrStr: "branch not found: fake-branch", + // }, + // { + // Query: "SELECT * from dolt_log(concat('fake', '-', 'branch'));", + // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + // }, + // { + // Query: "SELECT * from dolt_log(hashof('main'));", + // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit3, '--not', hashof('main'));", + // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + // }, + // { + // Query: "SELECT * from dolt_log(@Commit1, LOWER(@Commit2));", + // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + // }, + // { + // Query: "SELECT parents from dolt_log();", + // ExpectedErrStr: `column "parents" could not be found in any table in scope`, + // }, + // { + // Query: "SELECT * from dolt_log('--decorate', 'invalid');", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('--decorate', 123);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT * from dolt_log('--decorate', null);", + // ExpectedErr: sql.ErrInvalidArgumentDetails, + // }, + // { + // Query: "SELECT refs from dolt_log();", + // ExpectedErrStr: `column "refs" could not be found in any table in scope`, + // }, + // { + // Query: "SELECT refs from dolt_log('--decorate', 'auto');", + // ExpectedErrStr: `column "refs" could not be found in any table in scope`, + // }, + // { + // Query: "SELECT refs from dolt_log('--decorate', 'no');", + // ExpectedErrStr: `column "refs" could not be found in any table in scope`, + // }, + // }, + // }, { Name: "basic case with one revision", SetUpScript: []string{ From b214fb3608ed383b641c61f6c3d69e6530755b9e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 8 May 2023 14:57:04 -0700 Subject: [PATCH 027/167] Fixed deadlock in db creation --- go/libraries/doltcore/sqle/database_provider.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 4a76e1e62f..3de5591532 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -388,16 +388,7 @@ func (p DoltDatabaseProvider) CreateCollatedDatabase(ctx *sql.Context, name stri sess := dsess.DSessFromSess(ctx.Session) newEnv := env.Load(ctx, env.GetCurrentUserHomeDir, newFs, p.dbFactoryUrl, "TODO") - // if currentDB is empty, it will create the database with the default format which is the old format newDbStorageFormat := types.Format_Default - if curDB := sess.GetCurrentDatabase(); curDB != "" { - if sess.HasDB(ctx, curDB) { - if ddb, ok := sess.GetDoltDB(ctx, curDB); ok { - newDbStorageFormat = ddb.ValueReadWriter().Format() - } - } - } - err = newEnv.InitRepo(ctx, newDbStorageFormat, sess.Username(), sess.Email(), p.defaultBranch) if err != nil { return err From 5676d6e95b0b2ebce34749cf478b0ecb7b14b933 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 8 May 2023 15:22:39 -0700 Subject: [PATCH 028/167] Fixed nil db error --- .../doltcore/sqle/database_provider.go | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 3de5591532..b5d451b76f 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1074,6 +1074,9 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds if err != nil { return nil, false, err } + if !ok { + return nil, false, nil + } return wrapForStandby(db, standby), true, nil } @@ -1249,11 +1252,9 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s RepoStateReader: srcDb.DbData().Rsr, } - var db dsess.SqlDatabase - switch v := srcDb.(type) { - case Database: - db = Database{ + case ReadOnlyDatabase: + db := Database{ name: srcDb.Name(), ddb: v.ddb, rsw: static, @@ -1263,8 +1264,20 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s revision: revSpec, revType: dsess.RevisionTypeBranch, } + return ReadOnlyDatabase{db}, nil + case Database: + return Database{ + name: srcDb.Name(), + ddb: v.ddb, + rsw: static, + rsr: static, + gs: v.gs, + editOpts: v.editOpts, + revision: revSpec, + revType: dsess.RevisionTypeBranch, + }, nil case ReadReplicaDatabase: - db = ReadReplicaDatabase{ + return ReadReplicaDatabase{ Database: Database{ name: srcDb.Name(), ddb: v.ddb, @@ -1279,10 +1292,10 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s srcDB: v.srcDB, tmpDir: v.tmpDir, limiter: newLimiter(), - } + }, nil + default: + panic(fmt.Sprintf("unrecognized type of database %T", srcDb)) } - - return db, nil } func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.InitialDbState, error) { @@ -1350,7 +1363,7 @@ func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.I } func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string) (ReadOnlyDatabase, error) { - db := ReadOnlyDatabase{Database: Database{ + return ReadOnlyDatabase{Database: Database{ name: srcDb.Name(), ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, @@ -1358,9 +1371,7 @@ func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string) (Read editOpts: srcDb.editOpts, revision: revSpec, revType: dsess.RevisionTypeTag, - }} - - return db, nil + }}, nil } func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.InitialDbState, error) { @@ -1392,7 +1403,7 @@ func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.In } func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string) (ReadOnlyDatabase, error) { - db := ReadOnlyDatabase{Database: Database{ + return ReadOnlyDatabase{Database: Database{ name: srcDb.Name(), ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, @@ -1400,9 +1411,7 @@ func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string) (R editOpts: srcDb.editOpts, revision: revSpec, revType: dsess.RevisionTypeCommit, - }} - - return db, nil + }}, nil } func initialStateForCommit(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.InitialDbState, error) { From 41514186b4a114f0307aad9b1925f2f3a3291379 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 9 May 2023 11:21:09 -0700 Subject: [PATCH 029/167] Implemented UseDatabase, cleaned up head ref --- .../doltcore/sqle/dfunctions/active_branch.go | 3 + go/libraries/doltcore/sqle/dsess/session.go | 36 ++++- .../sqle/enginetest/dolt_engine_test.go | 133 +++++++++++++----- 3 files changed, 130 insertions(+), 42 deletions(-) diff --git a/go/libraries/doltcore/sqle/dfunctions/active_branch.go b/go/libraries/doltcore/sqle/dfunctions/active_branch.go index ddb987482d..d5ee1c05b3 100644 --- a/go/libraries/doltcore/sqle/dfunctions/active_branch.go +++ b/go/libraries/doltcore/sqle/dfunctions/active_branch.go @@ -49,6 +49,9 @@ func (ab *ActiveBranchFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, er if err != nil { return nil, err } + if currentBranchRef == nil { + return nil, nil + } branches, err := ddb.GetBranches(ctx) if err != nil { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 31e46815f3..74c279ddf2 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -925,6 +925,28 @@ func (d *DoltSession) SwitchWorkingSet( return nil } +func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { + sdb, ok := db.(SqlDatabase) + if !ok { + return fmt.Errorf("expected a SqlDatabase, got %T", db) + } + + branchState, ok, err := d.lookupDbState(ctx, db.Name()) + if err != nil { + return err + } + if !ok { + return sql.ErrDatabaseNotFound.New(db.Name()) + } + + d.mu.Lock() + defer d.mu.Unlock() + branchState.dbState.currRevSpec = sdb.Revision() + branchState.dbState.currRevType = sdb.RevisionType() + + return nil +} + func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.WorkingSet, error) { sessionState, _, err := d.LookupDbState(ctx, dbName) if err != nil { @@ -1054,6 +1076,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { tmpDir, err := dbState.DbData.Rsw.TempTableFilesDir() if err != nil { + d.mu.Unlock() if errors.Is(err, env.ErrDoltRepositoryNotFound) { return env.ErrFailedToAccessDB.New(dbState.Db.Name()) } @@ -1165,16 +1188,19 @@ func (d *DoltSession) GetAllTemporaryTables(ctx *sql.Context, db string) ([]sql. // CWBHeadRef returns the branch ref for this session HEAD for the database named func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef, error) { - dbState, _, err := d.LookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } - - if dbState.WorkingSet() == nil { + if !ok { + return nil, sql.ErrDatabaseNotFound.New(dbName) + } + + if branchState.dbState.currRevType != RevisionTypeBranch { return nil, nil } - - return dbState.WorkingSet().Ref().ToHeadRef() + + return ref.NewBranchRef(branchState.dbState.currRevSpec), nil } func (d *DoltSession) Username() string { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 57fd14b758..4de56274b2 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -115,47 +115,106 @@ func TestSingleQuery(t *testing.T) { // Convenience test for debugging a single query. Unskip and set to the desired query. func TestSingleScript(t *testing.T) { - t.Skip() - var scripts = []queries.ScriptTest{ - { - Name: "parallel column updates (repro issue #4547)", - SetUpScript: []string{ - "SET dolt_allow_commit_conflicts = on;", - "create table t (rowId int not null, col1 varchar(255), col2 varchar(255), keyCol varchar(60), dataA varchar(255), dataB varchar(255), PRIMARY KEY (rowId), UNIQUE KEY uniqKey (col1, col2, keyCol));", - "insert into t (rowId, col1, col2, keyCol, dataA, dataB) values (1, '1', '2', 'key-a', 'test1', 'test2')", - "CALL DOLT_COMMIT('-Am', 'new table');", - - "CALL DOLT_CHECKOUT('-b', 'other');", - "update t set dataA = 'other'", - "CALL DOLT_COMMIT('-am', 'update data other');", - - "CALL DOLT_CHECKOUT('main');", - "update t set dataB = 'main'", - "CALL DOLT_COMMIT('-am', 'update on main');", + // t.Skip() + + var script = queries.ScriptTest{ + Name: "database revision specs: Ancestor references", + SetUpScript: []string{ + "create table t01 (pk int primary key, c1 int)", + "call dolt_commit('-Am', 'creating table t01 on main');", + "call dolt_branch('branch1');", + "insert into t01 values (1, 1), (2, 2);", + "call dolt_commit('-am', 'adding rows to table t01 on main');", + "insert into t01 values (3, 3);", + "call dolt_commit('-am', 'adding another row to table t01 on main');", + "call dolt_tag('tag1');", + "call dolt_checkout('branch1');", + "insert into t01 values (100, 100), (200, 200);", + "call dolt_commit('-am', 'inserting rows in t01 on branch1');", + "insert into t01 values (1000, 1000);", + "call dolt_commit('-am', 'inserting another row in t01 on branch1');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "show databases;", + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, - Assertions: []queries.ScriptTestAssertion{ - { - Query: "CALL DOLT_MERGE('other')", - Expected: []sql.Row{{"child", uint64(1)}}, - }, - { - Query: "SELECT * from dolt_constraint_violations_t", - Expected: []sql.Row{}, - }, - { - Query: "SELECT * from t", - Expected: []sql.Row{ - {1, "1", "2", "key-a", "other", "main"}, - }, - }, + { + Query: "use `mydb/tag1~`;", + Expected: []sql.Row{}, + }, + { + // The database name is always the base name, never the revision specifier + Query: "select database()", + Expected: []sql.Row{{"mydb"}}, + }, + { + // The branch is nil in the case of a non-branch revision DB + Query: "select active_branch()", + Expected: []sql.Row{{nil}}, + }, + { + // The branch is nil in the case of a non-branch revision DB + Query: "select active_revision()", + Expected: []sql.Row{{"tag1~"}}, + }, + { + Query: "select * from t01;", + Expected: []sql.Row{{1, 1}, {2, 2}}, + }, + { + Query: "select * from `mydb/tag1^`.t01;", + Expected: []sql.Row{{1, 1}, {2, 2}}, + }, + { + // Only merge commits are valid for ^2 ancestor spec + Query: "select * from `mydb/tag1^2`.t01;", + ExpectedErrStr: "invalid ancestor spec", + }, + { + Query: "select * from `mydb/tag1~1`.t01;", + Expected: []sql.Row{{1, 1}, {2, 2}}, + }, + { + Query: "select * from `mydb/tag1~2`.t01;", + Expected: []sql.Row{}, + }, + { + Query: "select * from `mydb/tag1~3`.t01;", + ExpectedErr: sql.ErrTableNotFound, + }, + { + Query: "select * from `mydb/tag1~20`.t01;", + ExpectedErrStr: "invalid ancestor spec", + }, + { + Query: "select * from `mydb/branch1~`.t01;", + Expected: []sql.Row{{100, 100}, {200, 200}}, + }, + { + Query: "select * from `mydb/branch1^`.t01;", + Expected: []sql.Row{{100, 100}, {200, 200}}, + }, + { + Query: "select * from `mydb/branch1~2`.t01;", + Expected: []sql.Row{}, + }, + { + Query: "select * from `mydb/branch1~3`.t01;", + ExpectedErr: sql.ErrTableNotFound, }, }, } - harness := newDoltHarness(t) - for _, test := range scripts { - enginetest.TestScript(t, harness, test) - } + tcc := &testCommitClock{} + cleanup := installTestCommitClock(tcc) + defer cleanup() + + sql.RunWithNowFunc(tcc.Now, func() error { + harness := newDoltHarness(t) + enginetest.TestScript(t, harness, script) + return nil + }) } func TestSingleQueryPrepared(t *testing.T) { @@ -1443,7 +1502,7 @@ func installTestCommitClock(tcc *testCommitClock) func() { // TestSingleTransactionScript is a convenience method for debugging a single transaction test. Unskip and set to the // desired test. func TestSingleTransactionScript(t *testing.T) { - // t.Skip() + t.Skip() tcc := &testCommitClock{} cleanup := installTestCommitClock(tcc) From 49457a074a61a2d459db945733b7f54ffcde9ea6 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 9 May 2023 11:59:08 -0700 Subject: [PATCH 030/167] Small simplification, still not working --- go/libraries/doltcore/sqle/dsess/session.go | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 74c279ddf2..817268dd5a 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -844,7 +844,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. } branchState.workingSet = ws - err = d.setSessionVarsForDb(ctx, dbName) + err = d.setSessionVarsForDb(ctx, dbName, branchState) if err != nil { return err } @@ -1074,7 +1074,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { sessionState = NewEmptyDatabaseSessionState() d.dbStates[strings.ToLower(baseName)] = sessionState - tmpDir, err := dbState.DbData.Rsw.TempTableFilesDir() + sessionState.tmpFileDir, err = dbState.DbData.Rsw.TempTableFilesDir() if err != nil { d.mu.Unlock() if errors.Is(err, env.ErrDoltRepositoryNotFound) { @@ -1082,18 +1082,16 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } return err } - sessionState.tmpFileDir = tmpDir - - // TODO: is this right? - sessionState.currRevSpec = db.Revision() + + sessionState.dbName = baseName sessionState.currRevType = db.RevisionType() + sessionState.currRevSpec = db.Revision() } branchState.dbState = sessionState sessionState.heads[strings.ToLower(rev)] = branchState d.mu.Unlock() - sessionState.dbName = baseName // TODO: this doesn't seem right, shouldn't be a revision DB sessionState.db = db @@ -1151,7 +1149,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { branchState.headCommit = dbState.HeadCommit if sessionState.Err == nil { - return d.setSessionVarsForDb(ctx, db.Name()) + return d.setSessionVarsForDb(ctx, db.Name(), branchState) } return nil @@ -1216,12 +1214,7 @@ func (d *DoltSession) BatchMode() batchMode { } // setSessionVarsForDb updates the three session vars that track the value of the session root hashes -func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string) error { - state, _, err := d.lookupDbState(ctx, dbName) - if err != nil { - return err - } - +func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state *branchState) error { // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here if state.WorkingSet() != nil { From cad5aec55da4be729f04e7ba807ad18277c76304 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 9 May 2023 13:00:19 -0700 Subject: [PATCH 031/167] Added a RevisionQualifiedName method to SqlDatabase, use it everywhere --- .../doltcore/sqle/clusterdb/database.go | 2 +- go/libraries/doltcore/sqle/database.go | 21 +++++++++++++------ .../sqle/dprocedures/dolt_checkout.go | 10 +++------ go/libraries/doltcore/sqle/dsess/session.go | 2 ++ .../sqle/dsess/session_db_provider.go | 6 +++--- .../sqle/enginetest/dolt_engine_test.go | 4 ++++ go/libraries/doltcore/sqle/tables.go | 12 +++++------ .../doltcore/sqle/user_space_database.go | 2 +- 8 files changed, 35 insertions(+), 24 deletions(-) diff --git a/go/libraries/doltcore/sqle/clusterdb/database.go b/go/libraries/doltcore/sqle/clusterdb/database.go index 8ce0a88e58..3240bc513c 100644 --- a/go/libraries/doltcore/sqle/clusterdb/database.go +++ b/go/libraries/doltcore/sqle/clusterdb/database.go @@ -118,7 +118,7 @@ func (db database) RevisionType() dsess.RevisionType { return dsess.RevisionTypeNone } -func (db database) BaseName() string { +func (db database) RevisionQualifiedName() string { return db.Name() } diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index f49d58f1df..5be286a970 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -145,6 +145,15 @@ func (db Database) Name() string { return db.name } +// RevisionQualifiedName returns the name of this database including its revision qualifier, if any. This method should +// be used whenever accessing internal state of a database and its tables. +func (db Database) RevisionQualifiedName() string { + if db.revision == "" { + return db.name + } + return db.name + dsess.DbRevisionDelimiter + db.revision +} + // GetDoltDB gets the underlying DoltDB of the Database func (db Database) GetDoltDB() *doltdb.DoltDB { return db.ddb @@ -378,7 +387,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds map[string]env.Remote{}, map[string]env.BranchConfig{}, map[string]env.Remote{}) - ws, err := sess.WorkingSet(ctx, db.name) + ws, err := sess.WorkingSet(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err } @@ -534,7 +543,7 @@ func (db Database) GetTableNamesAsOf(ctx *sql.Context, time interface{}) ([]stri // getTable returns the user table with the given name from the root given func (db Database) getTable(ctx *sql.Context, root *doltdb.RootValue, tableName string) (sql.Table, bool, error) { sess := dsess.DSessFromSess(ctx.Session) - dbState, ok, err := sess.LookupDbState(ctx, db.name) + dbState, ok, err := sess.LookupDbState(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err } @@ -635,7 +644,7 @@ func filterDoltInternalTables(tblNames []string) []string { // GetRoot returns the root value for this database session func (db Database) GetRoot(ctx *sql.Context) (*doltdb.RootValue, error) { sess := dsess.DSessFromSess(ctx.Session) - dbState, ok, err := sess.LookupDbState(ctx, db.Name()) + dbState, ok, err := sess.LookupDbState(ctx, db.RevisionQualifiedName()) if err != nil { return nil, err } @@ -648,7 +657,7 @@ func (db Database) GetRoot(ctx *sql.Context) (*doltdb.RootValue, error) { func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) { sess := dsess.DSessFromSess(ctx.Session) - dbState, ok, err := sess.LookupDbState(ctx, db.Name()) + dbState, ok, err := sess.LookupDbState(ctx, db.RevisionQualifiedName()) if err != nil { return nil, err } @@ -1007,7 +1016,7 @@ func (db Database) RenameTable(ctx *sql.Context, oldName, newName string) error // Flush flushes the current batch of outstanding changes and returns any errors. func (db Database) Flush(ctx *sql.Context) error { sess := dsess.DSessFromSess(ctx.Session) - dbState, _, err := sess.LookupDbState(ctx, db.Name()) + dbState, _, err := sess.LookupDbState(ctx, db.RevisionQualifiedName()) if err != nil { return err } @@ -1045,7 +1054,7 @@ func (db Database) GetViewDefinition(ctx *sql.Context, viewName string) (sql.Vie } ds := dsess.DSessFromSess(ctx.Session) - dbState, _, err := ds.LookupDbState(ctx, db.name) + dbState, _, err := ds.LookupDbState(ctx, db.RevisionQualifiedName()) if err != nil { return sql.ViewDefinition{}, false, err } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index 32769ad037..9022b2b19d 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -172,6 +172,7 @@ func createWorkingSetForLocalBranch(ctx *sql.Context, ddb *doltdb.DoltDB, branch } // getRevisionForRevisionDatabase returns the root database name and revision for a database, or just the root database name if the specified db name is not a revision database. +// TODO: this is no longer necessary, kill it func getRevisionForRevisionDatabase(ctx *sql.Context, dbName string) (string, string, error) { doltsess, ok := ctx.Session.(*dsess.DoltSession) if !ok { @@ -185,13 +186,8 @@ func getRevisionForRevisionDatabase(ctx *sql.Context, dbName string) (string, st if !ok { return "", "", sql.ErrDatabaseNotFound.New(dbName) } - - rdb, ok := db.(dsess.RevisionDatabase) - if !ok { - return dbName, "", nil - } - - return rdb.BaseName(), rdb.Revision(), nil + + return db.Name(), db.Revision(), nil } // checkoutRemoteBranch checks out a remote branch creating a new local branch with the same name as the remote branch diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 817268dd5a..583ca20e56 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -818,6 +818,7 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R // Unlike setting the working root, this method always marks the database state dirty. func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roots) error { // TODO: handle HEAD here? + // TODO: need to make sure we use a revision qualified DB name here sessionState, _, err := d.LookupDbState(ctx, dbName) if err != nil { return err @@ -948,6 +949,7 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { } func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.WorkingSet, error) { + // TODO: need to make sure we use a revision qualified DB name here sessionState, _, err := d.LookupDbState(ctx, dbName) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index e3c46c16cd..59820e619b 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -38,9 +38,9 @@ type RevisionDatabase interface { Revision() string // RevisionType returns the type of revision this database is pinned to. RevisionType() RevisionType - // BaseName returns the name of the database without the revision specifier. E.g.if the database is named - // "myDB/master", BaseName returns "myDB". - BaseName() string + // RevisionQualiedName returns the fully qualified name of the database, which includes the revision if one is + // specified. + RevisionQualifiedName() string } // RevisionType represents the type of revision a database is pinned to. For branches and tags, the revision is a diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 4de56274b2..0c933cdd4b 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -162,6 +162,10 @@ func TestSingleScript(t *testing.T) { Query: "select * from t01;", Expected: []sql.Row{{1, 1}, {2, 2}}, }, + { + Query: "select * from `mydb/tag1`.t01;", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + }, { Query: "select * from `mydb/tag1^`.t01;", Expected: []sql.Row{{1, 1}, {2, 2}}, diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 34bae29e99..230280018b 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -244,7 +244,7 @@ func (t *DoltTable) GetIndexes(ctx *sql.Context) ([]sql.Index, error) { } sess := dsess.DSessFromSess(ctx.Session) - dbState, ok, err := sess.LookupDbState(ctx, t.db.Name()) + dbState, ok, err := sess.LookupDbState(ctx, t.db.RevisionQualifiedName()) if err != nil { return nil, err } @@ -520,7 +520,7 @@ func (t *WritableDoltTable) getTableEditor(ctx *sql.Context) (ed writer.TableWri } } - state, _, err := ds.LookupDbState(ctx, t.db.name) + state, _, err := ds.LookupDbState(ctx, t.db.RevisionQualifiedName()) if err != nil { return nil, err } @@ -635,13 +635,13 @@ func (t *WritableDoltTable) truncate( } } - ws, err := sess.WorkingSet(ctx, t.db.name) + ws, err := sess.WorkingSet(ctx, t.db.RevisionQualifiedName()) if err != nil { return nil, err } if schema.HasAutoIncrement(sch) { - ddb, _ := sess.GetDoltDB(ctx, t.db.name) + ddb, _ := sess.GetDoltDB(ctx, t.db.RevisionQualifiedName()) err = t.db.removeTableFromAutoIncrementTracker(ctx, t.Name(), ddb, ws.Ref()) if err != nil { return nil, err @@ -1248,7 +1248,7 @@ func (t *AlterableDoltTable) RewriteInserter( sess := dsess.DSessFromSess(ctx.Session) // Begin by creating a new table with the same name and the new schema, then removing all its existing rows - dbState, ok, err := sess.LookupDbState(ctx, t.db.Name()) + dbState, ok, err := sess.LookupDbState(ctx, t.db.RevisionQualifiedName()) if err != nil { return nil, err } @@ -2377,7 +2377,7 @@ func (t *AlterableDoltTable) updateFromRoot(ctx *sql.Context, root *doltdb.RootV // When we update this table we need to also clear any cached versions of the object, since they may now have // incorrect schema information sess := dsess.DSessFromSess(ctx.Session) - dbState, ok, err := sess.LookupDbState(ctx, t.db.name) + dbState, ok, err := sess.LookupDbState(ctx, t.db.RevisionQualifiedName()) if !ok { return fmt.Errorf("no db state found for %s", t.db.name) } diff --git a/go/libraries/doltcore/sqle/user_space_database.go b/go/libraries/doltcore/sqle/user_space_database.go index 285e090767..cb7bba625a 100644 --- a/go/libraries/doltcore/sqle/user_space_database.go +++ b/go/libraries/doltcore/sqle/user_space_database.go @@ -115,6 +115,6 @@ func (db *UserSpaceDatabase) RevisionType() dsess.RevisionType { return dsess.RevisionTypeNone } -func (db *UserSpaceDatabase) BaseName() string { +func (db *UserSpaceDatabase) RevisionQualifiedName() string { return db.Name() } From 8d0b6a7ab9d0e5161f900936383dd303acadfbc3 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 9 May 2023 16:38:38 -0700 Subject: [PATCH 032/167] Fixed yet another bug in db session init --- .../doltcore/sqle/database_provider.go | 22 +++-- go/libraries/doltcore/sqle/dsess/session.go | 24 +++++- .../sqle/enginetest/dolt_engine_test.go | 85 +++++++++++-------- 3 files changed, 89 insertions(+), 42 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index b5d451b76f..dffb05621c 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1064,12 +1064,24 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds // The db map only contains base databases, not revision DBs. Convert to a revision DB for creation. if !isRevisionDb { - // TODO: capture the initial checked out head at startup, don't get it here every time - // TODO: shouldn't use CWBHeadRef here, should come from the session's working set - headRef := db.DbData().Rsr.CWBHeadRef() - name = baseName + dsess.DbRevisionDelimiter + headRef.GetPath() + sess := dsess.DSessFromSess(ctx.Session) + + // To find the correct revision DB for this unqualified name, we need to look into the session state. A newly + // created session may not have any info on current head stored yet, in which case we get the default branch for + // the db itself instead. + head, ok, err := sess.CurrentHead(ctx, baseName) + if err != nil { + return nil, false, err + } + + if !ok { + headRef := db.DbData().Rsr.CWBHeadRef() + head = headRef.GetPath() + } + + name = baseName + dsess.DbRevisionDelimiter + head } - + db, ok, err := p.databaseForRevision(ctx, name) if err != nil { return nil, false, err diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 583ca20e56..6469fb2af1 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -932,7 +932,7 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { return fmt.Errorf("expected a SqlDatabase, got %T", db) } - branchState, ok, err := d.lookupDbState(ctx, db.Name()) + branchState, ok, err := d.lookupDbState(ctx, sdb.RevisionQualifiedName()) if err != nil { return err } @@ -1203,6 +1203,28 @@ func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef, return ref.NewBranchRef(branchState.dbState.currRevSpec), nil } +// CurrentHead returns the current head for the db named, which must be unqualifed. Used for bootstrap resolving the +// correct session head when a database name from the client is unqualified. +func (d *DoltSession) CurrentHead(ctx *sql.Context, dbName string) (string, bool, error) { + dbName = strings.ToLower(dbName) + + var baseName, rev string + baseName, rev = splitDbName(dbName) + if rev != "" { + return "", false, fmt.Errorf("invalid database name: %s", dbName) + } + + d.mu.Lock() + dbState, ok := d.dbStates[baseName] + d.mu.Unlock() + + if ok { + return dbState.currRevSpec, true, nil + } + + return "", false, nil +} + func (d *DoltSession) Username() string { return d.username } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 0c933cdd4b..ae3e6d03e7 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -128,83 +128,96 @@ func TestSingleScript(t *testing.T) { "insert into t01 values (3, 3);", "call dolt_commit('-am', 'adding another row to table t01 on main');", "call dolt_tag('tag1');", - "call dolt_checkout('branch1');", - "insert into t01 values (100, 100), (200, 200);", - "call dolt_commit('-am', 'inserting rows in t01 on branch1');", - "insert into t01 values (1000, 1000);", - "call dolt_commit('-am', 'inserting another row in t01 on branch1');", + // "call dolt_checkout('branch1');", + // "insert into t01 values (100, 100), (200, 200);", + // "call dolt_commit('-am', 'inserting rows in t01 on branch1');", + // "insert into t01 values (1000, 1000);", + // "call dolt_commit('-am', 'inserting another row in t01 on branch1');", }, Assertions: []queries.ScriptTestAssertion{ - { - Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, - }, + // { + // Query: "show databases;", + // Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, + // }, { Query: "use `mydb/tag1~`;", Expected: []sql.Row{}, }, + // { + // Query: "select commit_hash, date, message from dolt_log order by date;", + // Expected: []sql.Row{ + // {"j131v1r3cf6mrdjjjuqgkv4t33oa0l54", time.Date(1969, time.December, 31, 21, 0, 0, 0, time.Local), "Initialize data repository"}, + // {"kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "checkpoint enginetest database mydb"}, + // {"3kfav66courcnskj6ai5h5f55hg517e6", time.Date(1970, time.January, 1, 7, 0, 0, 0, time.Local), "creating table t01 on main"}, + // {"vsu7clg7ernin5hs4v78hlucghvmh4ti", time.Date(1970, time.January, 1, 14, 0, 0, 0, time.Local), "adding rows to table t01 on main"}, + // }, + // }, + // { + // Query: "select @@mydb_head", + // Expected: []sql.Row{{"vsu7clg7ernin5hs4v78hlucghvmh4ti"}}, + // }, + // { + // // The database name is always the base name, never the revision specifier + // Query: "select database()", + // Expected: []sql.Row{{"mydb"}}, + // }, + // { + // // The branch is nil in the case of a non-branch revision DB + // Query: "select active_branch()", + // Expected: []sql.Row{{nil}}, + // }, + // { + // // The branch is nil in the case of a non-branch revision DB + // Query: "select active_revision()", + // Expected: []sql.Row{{"tag1~"}}, + // }, { - // The database name is always the base name, never the revision specifier - Query: "select database()", - Expected: []sql.Row{{"mydb"}}, - }, - { - // The branch is nil in the case of a non-branch revision DB - Query: "select active_branch()", - Expected: []sql.Row{{nil}}, - }, - { - // The branch is nil in the case of a non-branch revision DB - Query: "select active_revision()", - Expected: []sql.Row{{"tag1~"}}, - }, - { - Query: "select * from t01;", + Query: "select * from t01 order by 1;", Expected: []sql.Row{{1, 1}, {2, 2}}, }, { - Query: "select * from `mydb/tag1`.t01;", + Query: "select * from `mydb/tag1`.t01 order by 1;", Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, }, { - Query: "select * from `mydb/tag1^`.t01;", + Query: "select * from `mydb/tag1^`.t01 order by 1;", Expected: []sql.Row{{1, 1}, {2, 2}}, }, { // Only merge commits are valid for ^2 ancestor spec - Query: "select * from `mydb/tag1^2`.t01;", + Query: "select * from `mydb/tag1^2`.t01 order by 1;", ExpectedErrStr: "invalid ancestor spec", }, { - Query: "select * from `mydb/tag1~1`.t01;", + Query: "select * from `mydb/tag1~1`.t01 order by 1;", Expected: []sql.Row{{1, 1}, {2, 2}}, }, { - Query: "select * from `mydb/tag1~2`.t01;", + Query: "select * from `mydb/tag1~2`.t01 order by 1;", Expected: []sql.Row{}, }, { - Query: "select * from `mydb/tag1~3`.t01;", + Query: "select * from `mydb/tag1~3`.t01 order by 1;", ExpectedErr: sql.ErrTableNotFound, }, { - Query: "select * from `mydb/tag1~20`.t01;", + Query: "select * from `mydb/tag1~20`.t01 order by 1;", ExpectedErrStr: "invalid ancestor spec", }, { - Query: "select * from `mydb/branch1~`.t01;", + Query: "select * from `mydb/branch1~`.t01 order by 1;", Expected: []sql.Row{{100, 100}, {200, 200}}, }, { - Query: "select * from `mydb/branch1^`.t01;", + Query: "select * from `mydb/branch1^`.t01 order by 1;", Expected: []sql.Row{{100, 100}, {200, 200}}, }, { - Query: "select * from `mydb/branch1~2`.t01;", + Query: "select * from `mydb/branch1~2`.t01 order by 1;", Expected: []sql.Row{}, }, { - Query: "select * from `mydb/branch1~3`.t01;", + Query: "select * from `mydb/branch1~3`.t01 order by 1;", ExpectedErr: sql.ErrTableNotFound, }, }, From 5254bda215b370d0883acda04e50ba4a85394f08 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 9 May 2023 16:42:38 -0700 Subject: [PATCH 033/167] Moved sessin cache from db state to branch state, since it's possible the same root value could already apply to another branch head, and it's important that the tables in the cache have the correct db assigned to them --- .../sqle/dsess/database_session_state.go | 18 +++++++++++------- go/libraries/doltcore/sqle/dsess/session.go | 5 ++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index d0d2843149..a72ae334ea 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -76,10 +76,7 @@ type DatabaseSessionState struct { dirty bool // tmpFileDir is the directory to use for temporary files for this database tmpFileDir string - - // sessionCache is a collection of cached values used to speed up performance - sessionCache *SessionCache - + // Same as InitialDbState.Err, this signifies that this // DatabaseSessionState is invalid. LookupDbState returning a // DatabaseSessionState with Err != nil will return that err. @@ -88,9 +85,7 @@ type DatabaseSessionState struct { func NewEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ - sessionCache: newSessionCache(), heads: make(map[string]*branchState), - // TODO: current head? } } @@ -123,6 +118,15 @@ type branchState struct { writeSession writer.WriteSession // readOnly is true if this database is read only readOnly bool + // sessionCache is a collection of cached values used to speed up performance + sessionCache *SessionCache +} + +func NewEmptyBranchState(dbState *DatabaseSessionState) *branchState { + return &branchState{ + dbState: dbState, + sessionCache: newSessionCache(), + } } func (d *branchState) WorkingRoot() *doltdb.RootValue { @@ -140,7 +144,7 @@ func (d *branchState) WriteSession() writer.WriteSession { } func (d *branchState) SessionCache() *SessionCache { - return d.dbState.sessionCache + return d.sessionCache } func (d branchState) EditOpts() editor.Options { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 6469fb2af1..e21f2a5bcd 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1060,7 +1060,6 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { // TODO: get rid of this, only define these for base names DefineSystemVariablesForDB(db.Name()) - branchState := &branchState{} baseName, rev := SplitRevisionDbName(db) DefineSystemVariablesForDB(baseName) @@ -1089,8 +1088,8 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { sessionState.currRevType = db.RevisionType() sessionState.currRevSpec = db.Revision() } - - branchState.dbState = sessionState + + branchState := NewEmptyBranchState(sessionState) sessionState.heads[strings.ToLower(rev)] = branchState d.mu.Unlock() From 34563332363b183cf719abf01a2fbad54553466e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 10:11:01 -0700 Subject: [PATCH 034/167] Fixed drop database semantics, cleaned up some qualifier access --- .../doltcore/sqle/database_provider.go | 31 ++------ go/libraries/doltcore/sqle/dsess/session.go | 53 +++++-------- .../doltcore/sqle/dsess/transactions.go | 2 + .../sqle/enginetest/dolt_engine_test.go | 74 +++++++++---------- go/libraries/doltcore/sqle/tables.go | 3 +- 5 files changed, 64 insertions(+), 99 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index dffb05621c..c35d291e16 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -599,11 +599,8 @@ func (p DoltDatabaseProvider) cloneDatabaseFromRemote( // DropDatabase implements the sql.MutableDatabaseProvider interface func (p DoltDatabaseProvider) DropDatabase(ctx *sql.Context, name string) error { - isRevisionDatabase, err := p.isRevisionDatabase(ctx, name) - if err != nil { - return err - } - if isRevisionDatabase { + _, revision := dsess.SplitRevDbName(name) + if revision != "" { return fmt.Errorf("unable to drop revision database: %s", name) } @@ -618,7 +615,7 @@ func (p DoltDatabaseProvider) DropDatabase(ctx *sql.Context, name string) error db := p.databases[dbKey] ddb := db.(Database).ddb - err = ddb.Close() + err := ddb.Close() if err != nil { return err } @@ -1140,21 +1137,6 @@ func (p DoltDatabaseProvider) TableFunction(_ *sql.Context, name string) (sql.Ta return nil, sql.ErrTableFunctionNotFound.New(name) } -// isRevisionDatabase returns true if the specified dbName represents a database that is tied to a specific -// branch or commit from a database (e.g. "dolt/branch1"). -func (p DoltDatabaseProvider) isRevisionDatabase(ctx *sql.Context, dbName string) (bool, error) { - db, ok, err := p.SessionDatabase(ctx, dbName) - if err != nil { - return false, err - } - if !ok { - return false, sql.ErrDatabaseNotFound.New(dbName) - } - - _, rev := dsess.SplitRevisionDbName(db) - return rev != "", nil -} - // ensureReplicaHeadExists tries to pull the latest version of a remote branch. Will fail if the branch // does not exist on the ReadReplicaDatabase's remote. func (p DoltDatabaseProvider) ensureReplicaHeadExists(ctx *sql.Context, branch string, db ReadReplicaDatabase) error { @@ -1311,10 +1293,9 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s } func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.InitialDbState, error) { - _, revSpec := dsess.SplitRevisionDbName(srcDb) + revSpec := srcDb.Revision() // TODO: this may be a disabled transaction, need to kill those - rootHash, err := dsess.TransactionRoot(ctx, srcDb) if err != nil { return dsess.InitialDbState{}, err @@ -1387,7 +1368,7 @@ func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string) (Read } func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.InitialDbState, error) { - _, revSpec := dsess.SplitRevisionDbName(srcDb) + revSpec := srcDb.Revision() tag := ref.NewTagRef(revSpec) cm, err := srcDb.DbData().Ddb.ResolveCommitRef(ctx, tag) @@ -1427,7 +1408,7 @@ func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string) (R } func initialStateForCommit(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.InitialDbState, error) { - _, revSpec := dsess.SplitRevisionDbName(srcDb) + revSpec := srcDb.Revision() spec, err := doltdb.NewCommitSpec(revSpec) if err != nil { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index e21f2a5bcd..8ec91acd64 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -48,6 +48,10 @@ const ( Batched ) +const ( + DbRevisionDelimiter = "/" +) + var ErrWorkingSetChanges = goerrors.NewKind("Cannot switch working set, session state is dirty. " + "Rollback or commit changes before changing working sets.") var ErrSessionNotPeristable = errors.New("session is not persistable") @@ -140,7 +144,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta dbName = strings.ToLower(dbName) var baseName, rev string - baseName, rev = splitDbName(dbName) + baseName, rev = SplitRevDbName(dbName) d.mu.Lock() dbState, ok := d.dbStates[baseName] @@ -166,12 +170,12 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta // No state for this db / branch combination yet, look it up from the provider. We use the unqualified DB name (no // branch) if the current DB has not yet been loaded into this session. It will resolve to that DB's default branch // in that case. - sessionDbName := dbName + revisionQualifiedName := dbName if rev != "" { - sessionDbName = revisionDbName(baseName, rev) + revisionQualifiedName = revisionDbName(baseName, rev) } - database, ok, err := d.provider.SessionDatabase(ctx, sessionDbName) + database, ok, err := d.provider.SessionDatabase(ctx, revisionQualifiedName) if err != nil { return nil, false, err } @@ -192,15 +196,14 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta return nil, false, sql.ErrDatabaseNotFound.New(dbName) } - _, rev = SplitRevisionDbName(database) - return dbState.heads[strings.ToLower(rev)], true, nil + return dbState.heads[strings.ToLower(database.Revision())], true, nil } func revisionDbName(baseName string, rev string) string { return baseName + DbRevisionDelimiter + rev } -func splitDbName(dbName string) (string, string) { +func SplitRevDbName(dbName string) (string, string) { var baseName, rev string parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) baseName = parts[0] @@ -871,7 +874,7 @@ func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref. d.mu.Lock() - baseName, _ := splitDbName(dbName) + baseName, _ := SplitRevDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { d.mu.Unlock() @@ -902,7 +905,7 @@ func (d *DoltSession) SwitchWorkingSet( d.mu.Lock() - baseName, _ := splitDbName(dbName) + baseName, _ := SplitRevDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { d.mu.Unlock() @@ -1057,14 +1060,11 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { // addDB adds the database given to this session. This establishes a starting root value for this session, as well as // other state tracking metadata. func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { - // TODO: get rid of this, only define these for base names DefineSystemVariablesForDB(db.Name()) - baseName, rev := SplitRevisionDbName(db) - - DefineSystemVariablesForDB(baseName) - - dbState, err := db.InitialDBState(ctx, rev) + baseName, rev := db.Name(), db.Revision() + // TODO: odd that we need to tell the DB what its own revision is here + dbState, err := db.InitialDBState(ctx, db.Revision()) if err != nil { return err } @@ -1208,7 +1208,7 @@ func (d *DoltSession) CurrentHead(ctx *sql.Context, dbName string) (string, bool dbName = strings.ToLower(dbName) var baseName, rev string - baseName, rev = splitDbName(dbName) + baseName, rev = SplitRevDbName(dbName) if rev != "" { return "", false, fmt.Errorf("invalid database name: %s", dbName) } @@ -1557,18 +1557,6 @@ func InitPersistedSystemVars(dEnv *env.DoltEnv) error { return nil } -// SplitRevisionDbName splits the given database name into its base and revision parts and returns them. Non-revision -// DBs use their full name as the base name, and empty string as the revision. -// TODO: get rid of this, should no longer be necessary -func SplitRevisionDbName(db SqlDatabase) (string, string) { - dbName := db.Name() - if db.Revision() != "" { - dbName = strings.TrimSuffix(dbName, DbRevisionDelimiter+db.Revision()) - } - - return dbName, db.Revision() -} - // TransactionRoot returns the noms root for the given database in the current transaction func TransactionRoot(ctx *sql.Context, db SqlDatabase) (hash.Hash, error) { tx, ok := ctx.GetTransaction().(*DoltTransaction) @@ -1577,15 +1565,10 @@ func TransactionRoot(ctx *sql.Context, db SqlDatabase) (hash.Hash, error) { return db.DbData().Ddb.NomsRoot(ctx) } - baseName, _ := SplitRevisionDbName(db) - nomsRoot, ok := tx.GetInitialRoot(baseName) + nomsRoot, ok := tx.GetInitialRoot(db.Name()) if !ok { return hash.Hash{}, fmt.Errorf("could not resolve initial root for database %s", db.Name()) } return nomsRoot, nil -} - -const ( - DbRevisionDelimiter = "/" -) +} \ No newline at end of file diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index be457d5e41..6bf99f047e 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -123,6 +123,8 @@ func (tx DoltTransaction) IsReadOnly() bool { return tx.tCharacteristic == sql.ReadOnly } +// GetInitialRoot returns the noms root hash for the db named, established when the transaction began. The dbName here +// is always the base name of the database, not the revision qualified one. func (tx DoltTransaction) GetInitialRoot(dbName string) (hash.Hash, bool) { startPoint, ok := tx.dbStartPoints[strings.ToLower(dbName)] return startPoint.rootHash, ok diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index ae3e6d03e7..8fc0707e11 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -128,49 +128,49 @@ func TestSingleScript(t *testing.T) { "insert into t01 values (3, 3);", "call dolt_commit('-am', 'adding another row to table t01 on main');", "call dolt_tag('tag1');", - // "call dolt_checkout('branch1');", - // "insert into t01 values (100, 100), (200, 200);", - // "call dolt_commit('-am', 'inserting rows in t01 on branch1');", - // "insert into t01 values (1000, 1000);", - // "call dolt_commit('-am', 'inserting another row in t01 on branch1');", + "call dolt_checkout('branch1');", + "insert into t01 values (100, 100), (200, 200);", + "call dolt_commit('-am', 'inserting rows in t01 on branch1');", + "insert into t01 values (1000, 1000);", + "call dolt_commit('-am', 'inserting another row in t01 on branch1');", }, Assertions: []queries.ScriptTestAssertion{ - // { - // Query: "show databases;", - // Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, - // }, + { + Query: "show databases;", + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, + }, { Query: "use `mydb/tag1~`;", Expected: []sql.Row{}, }, - // { - // Query: "select commit_hash, date, message from dolt_log order by date;", - // Expected: []sql.Row{ - // {"j131v1r3cf6mrdjjjuqgkv4t33oa0l54", time.Date(1969, time.December, 31, 21, 0, 0, 0, time.Local), "Initialize data repository"}, - // {"kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "checkpoint enginetest database mydb"}, - // {"3kfav66courcnskj6ai5h5f55hg517e6", time.Date(1970, time.January, 1, 7, 0, 0, 0, time.Local), "creating table t01 on main"}, - // {"vsu7clg7ernin5hs4v78hlucghvmh4ti", time.Date(1970, time.January, 1, 14, 0, 0, 0, time.Local), "adding rows to table t01 on main"}, - // }, - // }, - // { - // Query: "select @@mydb_head", - // Expected: []sql.Row{{"vsu7clg7ernin5hs4v78hlucghvmh4ti"}}, - // }, - // { - // // The database name is always the base name, never the revision specifier - // Query: "select database()", - // Expected: []sql.Row{{"mydb"}}, - // }, - // { - // // The branch is nil in the case of a non-branch revision DB - // Query: "select active_branch()", - // Expected: []sql.Row{{nil}}, - // }, - // { - // // The branch is nil in the case of a non-branch revision DB - // Query: "select active_revision()", - // Expected: []sql.Row{{"tag1~"}}, - // }, + { + Query: "select commit_hash, date, message from dolt_log order by date;", + Expected: []sql.Row{ + {"j131v1r3cf6mrdjjjuqgkv4t33oa0l54", time.Date(1969, time.December, 31, 21, 0, 0, 0, time.Local), "Initialize data repository"}, + {"kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "checkpoint enginetest database mydb"}, + {"3kfav66courcnskj6ai5h5f55hg517e6", time.Date(1970, time.January, 1, 7, 0, 0, 0, time.Local), "creating table t01 on main"}, + {"vsu7clg7ernin5hs4v78hlucghvmh4ti", time.Date(1970, time.January, 1, 14, 0, 0, 0, time.Local), "adding rows to table t01 on main"}, + }, + }, + { + Query: "select @@mydb_head", + Expected: []sql.Row{{"vsu7clg7ernin5hs4v78hlucghvmh4ti"}}, + }, + { + // The database name is always the base name, never the revision specifier + Query: "select database()", + Expected: []sql.Row{{"mydb"}}, + }, + { + // The branch is nil in the case of a non-branch revision DB + Query: "select active_branch()", + Expected: []sql.Row{{nil}}, + }, + { + // The branch is nil in the case of a non-branch revision DB + Query: "select active_revision()", + Expected: []sql.Row{{"tag1~"}}, + }, { Query: "select * from t01 order by 1;", Expected: []sql.Row{{1, 1}, {2, 2}}, diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 230280018b..889a9f2823 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -222,8 +222,7 @@ func (t *DoltTable) workingRoot(ctx *sql.Context) (*doltdb.RootValue, error) { return root, nil } -// getRoot returns the appropriate root value for this session. The only controlling factor -// is whether this is a temporary table or not. +// getRoot returns the current root value for this session, to be used for all table data access. func (t *DoltTable) getRoot(ctx *sql.Context) (*doltdb.RootValue, error) { return t.db.GetRoot(ctx) } From 400aae48ef2f8d1e532c3ea9e9a02edb520b9945 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 11:16:12 -0700 Subject: [PATCH 035/167] Fixed most revision db tests --- .../sqle/enginetest/dolt_engine_test.go | 100 ++++++++---------- .../doltcore/sqle/enginetest/dolt_queries.go | 40 ++++--- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 8fc0707e11..1a61a7bc18 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -118,43 +118,25 @@ func TestSingleScript(t *testing.T) { // t.Skip() var script = queries.ScriptTest{ - Name: "database revision specs: Ancestor references", + Name: "database revision specs: branch-qualified revision spec", SetUpScript: []string{ "create table t01 (pk int primary key, c1 int)", - "call dolt_commit('-Am', 'creating table t01 on main');", - "call dolt_branch('branch1');", + "call dolt_add('.')", + "call dolt_commit('-am', 'creating table t01 on main');", "insert into t01 values (1, 1), (2, 2);", "call dolt_commit('-am', 'adding rows to table t01 on main');", + "call dolt_branch('branch1');", "insert into t01 values (3, 3);", "call dolt_commit('-am', 'adding another row to table t01 on main');", - "call dolt_tag('tag1');", - "call dolt_checkout('branch1');", - "insert into t01 values (100, 100), (200, 200);", - "call dolt_commit('-am', 'inserting rows in t01 on branch1');", - "insert into t01 values (1000, 1000);", - "call dolt_commit('-am', 'inserting another row in t01 on branch1');", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, - }, - { - Query: "use `mydb/tag1~`;", + Query: "use mydb/branch1;", Expected: []sql.Row{}, }, { - Query: "select commit_hash, date, message from dolt_log order by date;", - Expected: []sql.Row{ - {"j131v1r3cf6mrdjjjuqgkv4t33oa0l54", time.Date(1969, time.December, 31, 21, 0, 0, 0, time.Local), "Initialize data repository"}, - {"kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "checkpoint enginetest database mydb"}, - {"3kfav66courcnskj6ai5h5f55hg517e6", time.Date(1970, time.January, 1, 7, 0, 0, 0, time.Local), "creating table t01 on main"}, - {"vsu7clg7ernin5hs4v78hlucghvmh4ti", time.Date(1970, time.January, 1, 14, 0, 0, 0, time.Local), "adding rows to table t01 on main"}, - }, - }, - { - Query: "select @@mydb_head", - Expected: []sql.Row{{"vsu7clg7ernin5hs4v78hlucghvmh4ti"}}, + Query: "show databases;", + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { // The database name is always the base name, never the revision specifier @@ -162,63 +144,65 @@ func TestSingleScript(t *testing.T) { Expected: []sql.Row{{"mydb"}}, }, { - // The branch is nil in the case of a non-branch revision DB Query: "select active_branch()", - Expected: []sql.Row{{nil}}, + Expected: []sql.Row{{"branch1"}}, }, { - // The branch is nil in the case of a non-branch revision DB - Query: "select active_revision()", - Expected: []sql.Row{{"tag1~"}}, - }, - { - Query: "select * from t01 order by 1;", + Query: "select * from t01", Expected: []sql.Row{{1, 1}, {2, 2}}, }, { - Query: "select * from `mydb/tag1`.t01 order by 1;", - Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + Query: "call dolt_checkout('main');", + Expected: []sql.Row{{0}}, }, { - Query: "select * from `mydb/tag1^`.t01 order by 1;", - Expected: []sql.Row{{1, 1}, {2, 2}}, + Query: "show databases;", + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { - // Only merge commits are valid for ^2 ancestor spec - Query: "select * from `mydb/tag1^2`.t01 order by 1;", - ExpectedErrStr: "invalid ancestor spec", + Query: "select database();", + Expected: []sql.Row{{"mydb"}}, }, { - Query: "select * from `mydb/tag1~1`.t01 order by 1;", - Expected: []sql.Row{{1, 1}, {2, 2}}, - }, - { - Query: "select * from `mydb/tag1~2`.t01 order by 1;", + Query: "use mydb/branch1;", Expected: []sql.Row{}, }, { - Query: "select * from `mydb/tag1~3`.t01 order by 1;", - ExpectedErr: sql.ErrTableNotFound, + Query: "call dolt_reset();", + Expected: []sql.Row{{0}}, }, { - Query: "select * from `mydb/tag1~20`.t01 order by 1;", - ExpectedErrStr: "invalid ancestor spec", + Query: "select database();", + Expected: []sql.Row{{"mydb"}}, }, { - Query: "select * from `mydb/branch1~`.t01 order by 1;", - Expected: []sql.Row{{100, 100}, {200, 200}}, + Query: "show databases;", + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { - Query: "select * from `mydb/branch1^`.t01 order by 1;", - Expected: []sql.Row{{100, 100}, {200, 200}}, + // Create a table in the working set to verify the main db + Query: "create table working_set_table(pk int primary key);", + Expected: []sql.Row{{gmstypes.NewOkResult(0)}}, }, { - Query: "select * from `mydb/branch1~2`.t01 order by 1;", + Query: "select table_name from dolt_diff where commit_hash='WORKING';", + Expected: []sql.Row{{"working_set_table"}}, + }, + { + Query: "use mydb;", Expected: []sql.Row{}, }, { - Query: "select * from `mydb/branch1~3`.t01 order by 1;", - ExpectedErr: sql.ErrTableNotFound, + Query: "select table_name from dolt_diff where commit_hash='WORKING';", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_checkout('branch1');", + Expected: []sql.Row{{0}}, + }, + { + Query: "select table_name from dolt_diff where commit_hash='WORKING';", + Expected: []sql.Row{{"working_set_table"}}, }, }, } @@ -1186,11 +1170,11 @@ func TestDoltRevisionDbScripts(t *testing.T) { }, { Query: "select database();", - Expected: []sql.Row{{"mydb/" + commithash}}, + Expected: []sql.Row{{"mydb"}}, }, { Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mydb/" + commithash}, {"mysql"}}, + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { Query: "select * from t01", diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 4891bbdf00..89eaf1056e 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -311,9 +311,14 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - // The database name should be the revision spec we started with, not its resolved hash - Query: "select database() regexp '^mydb/[0-9a-v]{32}$', database() = 'mydb/tag1~';", - Expected: []sql.Row{{false, true}}, + // The database name is always the base name, never the revision specifier + Query: "select database()", + Expected: []sql.Row{{"mydb"}}, + }, + { + // The branch is nil in the case of a non-branch revision DB + Query: "select active_branch()", + Expected: []sql.Row{{nil}}, }, { Query: "select * from t01;", @@ -384,12 +389,18 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "select database();", - Expected: []sql.Row{{"mydb/tag1"}}, + // The database name is always the base name, never the revision specifier + Query: "select database()", + Expected: []sql.Row{{"mydb"}}, + }, + { + // The branch is nil in the case of a non-branch revision DB + Query: "select active_branch()", + Expected: []sql.Row{{nil}}, }, { Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mydb/tag1"}, {"mysql"}}, + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { Query: "select * from t01;", @@ -444,11 +455,16 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ }, { Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mydb/branch1"}, {"mysql"}}, + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { - Query: "select database();", - Expected: []sql.Row{{"mydb/branch1"}}, + // The database name is always the base name, never the revision specifier + Query: "select database()", + Expected: []sql.Row{{"mydb"}}, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"branch1"}}, }, { Query: "select * from t01", @@ -476,18 +492,18 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ }, { Query: "select database();", - Expected: []sql.Row{{"mydb/branch1"}}, + Expected: []sql.Row{{"mydb"}}, }, { Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mydb/branch1"}, {"mysql"}}, + Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, }, { + // Create a table in the working set to verify the main db Query: "create table working_set_table(pk int primary key);", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - // Create a table in the working set to verify the main db Query: "select table_name from dolt_diff where commit_hash='WORKING';", Expected: []sql.Row{{"working_set_table"}}, }, From defa5ce19ef793f89c10b4df1ecd402dbb8fd84e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 13:38:37 -0700 Subject: [PATCH 036/167] Tests for dolt_checkout --- go/libraries/doltcore/sqle/database.go | 10 +- .../sqle/enginetest/dolt_engine_test.go | 10 ++ .../doltcore/sqle/enginetest/dolt_queries.go | 159 ++++++++++++++++++ 3 files changed, 174 insertions(+), 5 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 5be286a970..5a59018284 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -187,7 +187,7 @@ func (db Database) GetTableInsensitive(ctx *sql.Context, tblName string) (sql.Ta // We start by first checking whether the input table is a temporary table. Temporary tables with name `x` take // priority over persisted tables of name `x`. ds := dsess.DSessFromSess(ctx.Session) - if tbl, ok := ds.GetTemporaryTable(ctx, db.Name(), tblName); ok { + if tbl, ok := ds.GetTemporaryTable(ctx, db.RevisionQualifiedName(), tblName); ok { return tbl, ok, nil } @@ -273,8 +273,8 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds } } - suffix := tblName[len(doltdb.DoltDiffTablePrefix):] - dt, err := dtables.NewDiffTable(ctx, suffix, db.ddb, root, head) + tableName := tblName[len(doltdb.DoltDiffTablePrefix):] + dt, err := dtables.NewDiffTable(ctx, tableName, db.ddb, root, head) if err != nil { return nil, false, err } @@ -347,13 +347,13 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds case doltdb.DiffTableName: if head == nil { var err error - head, err = ds.GetHeadCommit(ctx, db.Name()) + head, err = ds.GetHeadCommit(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err } } - dt, found = dtables.NewUnscopedDiffTable(ctx, db.name, db.ddb, head), true + dt, found = dtables.NewUnscopedDiffTable(ctx, db.RevisionQualifiedName(), db.ddb, head), true case doltdb.ColumnDiffTableName: if head == nil { var err error diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 1a61a7bc18..1c45ece481 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1449,6 +1449,16 @@ func TestDoltGC(t *testing.T) { } } +func TestDoltCheckout(t *testing.T) { + for _, script := range DoltCheckoutScripts { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScript(t, h, script) + }() + } +} + func TestDoltBranch(t *testing.T) { for _, script := range DoltBranchScripts { func() { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 89eaf1056e..fbb2e5e25f 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -1910,6 +1910,165 @@ var BrokenHistorySystemTableScriptTests = []queries.ScriptTest{ }, } +var DoltCheckoutScripts = []queries.ScriptTest{ + { + Name: "dolt_checkout changes working set", + SetUpScript: []string{ + "create table t (a int primary key, b int);", + "call dolt_commit('-Am', 'creating table t');", + "call dolt_branch('b2');", + "call dolt_branch('b3');", + "insert into t values (1, 1);", + "call dolt_commit('-Am', 'added values on main');", + "call dolt_checkout('b2');", + "insert into t values (2, 2);", + "call dolt_commit('-am', 'added values on b2');", + "call dolt_checkout('b3');", + "insert into t values (3, 3);", + "call dolt_commit('-am', 'added values on b3');", + "call dolt_checkout('main');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{1, 1}}, + }, + { + Query: "call dolt_checkout('b2');", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b2"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{2, 2}}, + }, + { + Query: "call dolt_checkout('b3');", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b3"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{3, 3}}, + }, + { + Query: "call dolt_checkout('main');", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{1, 1}}, + }, + }, + }, + { + Name: "dolt_checkout mixed with USE statements", + SetUpScript: []string{ + "create table t (a int primary key, b int);", + "call dolt_commit('-Am', 'creating table t');", + "call dolt_branch('b2');", + "call dolt_branch('b3');", + "insert into t values (1, 1);", + "call dolt_commit('-Am', 'added values on main');", + "call dolt_checkout('b2');", + "insert into t values (2, 2);", + "call dolt_commit('-am', 'added values on b2');", + "call dolt_checkout('b3');", + "insert into t values (3, 3);", + "call dolt_commit('-am', 'added values on b3');", + "call dolt_checkout('main');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{1, 1}}, + }, + { + Query: "use `mydb/b2`;", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b2"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{2, 2}}, + }, + { + Query: "use `mydb/b3`;", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b3"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{3, 3}}, + }, + { + Query: "use `mydb/main`", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{1, 1}}, + }, + { + Query: "use `mydb`", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{1, 1}}, + }, + { + Query: "call dolt_checkout('b2');", + SkipResultsCheck: true, + }, + { + Query: "use `mydb`", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b2"}}, + }, + { + Query: "select * from t;", + Expected: []sql.Row{{2, 2}}, + }, + }, + }, +} + var DoltBranchScripts = []queries.ScriptTest{ { Name: "Create branches from HEAD with dolt_branch procedure", From b9de36dcc7166103e26e246bc6ee3016b74ab4bb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 13:46:33 -0700 Subject: [PATCH 037/167] Better test showing the current issue with checkout --- go/libraries/doltcore/sqle/enginetest/dolt_queries.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index fbb2e5e25f..37505be838 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -2053,6 +2053,15 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Query: "call dolt_checkout('b2');", SkipResultsCheck: true, }, + { + Query: "use `mydb/b3`", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b3"}}, + }, + // Since b2 was the last branch checked out with dolt_checkout, it's what mydb resolves to { Query: "use `mydb`", SkipResultsCheck: true, From 90d3ad6ec7faabd1609e65fcc0cf8e14b4f7f902 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 15:04:04 -0700 Subject: [PATCH 038/167] experiment, probably throw away --- go/libraries/doltcore/sqle/database.go | 17 +++---- .../doltcore/sqle/database_provider.go | 48 +++++++++++-------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 5a59018284..ab9bbfdd2b 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -48,14 +48,15 @@ var ErrSystemTableAlter = errors.NewKind("Cannot alter table %s: system tables c // Database implements sql.Database for a dolt DB. type Database struct { - name string - ddb *doltdb.DoltDB - rsr env.RepoStateReader - rsw env.RepoStateWriter - gs globalstate.GlobalState - editOpts editor.Options - revision string - revType dsess.RevisionType + name string + requestedName string + ddb *doltdb.DoltDB + rsr env.RepoStateReader + rsw env.RepoStateWriter + gs globalstate.GlobalState + editOpts editor.Options + revision string + revType dsess.RevisionType } var _ dsess.SqlDatabase = Database{} diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index c35d291e16..cb38e42e00 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -339,7 +339,7 @@ func (p DoltDatabaseProvider) allRevisionDbs(ctx *sql.Context, db dsess.SqlDatab revDbs := make([]sql.Database, len(branches)) for i, branch := range branches { - revDb, ok, err := p.databaseForRevision(ctx, fmt.Sprintf("%s/%s", db.Name(), branch.GetPath())) + revDb, ok, err := p.databaseForRevision(ctx, fmt.Sprintf("%s/%s", db.Name(), branch.GetPath()), "") if err != nil { return nil, err } @@ -716,12 +716,12 @@ func (p DoltDatabaseProvider) invalidateDbStateInAllSessions(ctx *sql.Context, n return nil } -func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string) (dsess.SqlDatabase, bool, error) { - if !strings.Contains(revDB, dsess.DbRevisionDelimiter) { +func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQualifiedName string, requestedName string) (dsess.SqlDatabase, bool, error) { + if !strings.Contains(revisionQualifiedName, dsess.DbRevisionDelimiter) { return nil, false, nil } - parts := strings.SplitN(revDB, dsess.DbRevisionDelimiter, 2) + parts := strings.SplitN(revisionQualifiedName, dsess.DbRevisionDelimiter, 2) baseName, rev := parts[0], parts[1] p.mu.RLock() @@ -753,10 +753,10 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string } } - db, err := revisionDbForBranch(ctx, srcDb, resolvedRevSpec) + db, err := revisionDbForBranch(ctx, srcDb, resolvedRevSpec, requestedName) // preserve original user case in the case of not found if sql.ErrDatabaseNotFound.Is(err) { - return nil, false, sql.ErrDatabaseNotFound.New(revDB) + return nil, false, sql.ErrDatabaseNotFound.New(revisionQualifiedName) } else if err != nil { return nil, false, err } @@ -775,7 +775,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string return nil, false, nil } - db, err := revisionDbForTag(ctx, srcDb.(Database), resolvedRevSpec) + db, err := revisionDbForTag(ctx, srcDb.(Database), resolvedRevSpec, requestedName) if err != nil { return nil, false, err } @@ -791,7 +791,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string if !ok { return nil, false, nil } - db, err := revisionDbForCommit(ctx, srcDb.(Database), rev) + db, err := revisionDbForCommit(ctx, srcDb.(Database), rev, requestedName) if err != nil { return nil, false, err } @@ -1048,7 +1048,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds // If the database doesn't exist and this is a read replica, attempt to clone it from the remote if !ok { var err error - db, err = p.databaseForClone(ctx, name) + db, err = p.databaseForClone(ctx, baseName) if err != nil { return nil, false, err @@ -1060,6 +1060,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds } // The db map only contains base databases, not revision DBs. Convert to a revision DB for creation. + revisionQualifiedName := name if !isRevisionDb { sess := dsess.DSessFromSess(ctx.Session) @@ -1076,10 +1077,10 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds head = headRef.GetPath() } - name = baseName + dsess.DbRevisionDelimiter + head + revisionQualifiedName = baseName + dsess.DbRevisionDelimiter + head } - db, ok, err := p.databaseForRevision(ctx, name) + db, ok, err := p.databaseForRevision(ctx, revisionQualifiedName, name) if err != nil { return nil, false, err } @@ -1237,7 +1238,7 @@ func isTag(ctx context.Context, db dsess.SqlDatabase, tagName string) (bool, err } // revisionDbForBranch returns a new database that is tied to the branch named by revSpec -func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec string) (dsess.SqlDatabase, error) { +func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec string, requestedName string) (dsess.SqlDatabase, error) { branch := ref.NewBranchRef(revSpec) static := staticRepoState{ @@ -1250,6 +1251,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s case ReadOnlyDatabase: db := Database{ name: srcDb.Name(), + requestedName: requestedName, ddb: v.ddb, rsw: static, rsr: static, @@ -1262,6 +1264,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s case Database: return Database{ name: srcDb.Name(), + requestedName: requestedName, ddb: v.ddb, rsw: static, rsr: static, @@ -1274,6 +1277,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s return ReadReplicaDatabase{ Database: Database{ name: srcDb.Name(), + requestedName: requestedName, ddb: v.ddb, rsw: static, rsr: static, @@ -1355,9 +1359,10 @@ func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.I return init, nil } -func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string) (ReadOnlyDatabase, error) { +func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { return ReadOnlyDatabase{Database: Database{ name: srcDb.Name(), + requestedName: requestedName, ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, rsr: srcDb.DbData().Rsr, @@ -1395,15 +1400,16 @@ func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.In return init, nil } -func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string) (ReadOnlyDatabase, error) { +func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { return ReadOnlyDatabase{Database: Database{ - name: srcDb.Name(), - ddb: srcDb.DbData().Ddb, - rsw: srcDb.DbData().Rsw, - rsr: srcDb.DbData().Rsr, - editOpts: srcDb.editOpts, - revision: revSpec, - revType: dsess.RevisionTypeCommit, + name: srcDb.Name(), + requestedName: requestedName, + ddb: srcDb.DbData().Ddb, + rsw: srcDb.DbData().Rsw, + rsr: srcDb.DbData().Rsr, + editOpts: srcDb.editOpts, + revision: revSpec, + revType: dsess.RevisionTypeCommit, }}, nil } From 8cb37ec2923ef1ecc919ee13c8cd55c0cba86f8a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 16:05:25 -0700 Subject: [PATCH 039/167] Added a RequestedName param, differentiate on it during USE statements --- .../doltcore/sqle/clusterdb/database.go | 4 ++++ go/libraries/doltcore/sqle/database.go | 9 ++++---- .../doltcore/sqle/database_provider.go | 7 +------ .../sqle/dsess/database_session_state.go | 3 +++ go/libraries/doltcore/sqle/dsess/session.go | 21 +++++++++++++------ .../sqle/dsess/session_db_provider.go | 5 ++++- .../doltcore/sqle/user_space_database.go | 4 ++++ 7 files changed, 35 insertions(+), 18 deletions(-) diff --git a/go/libraries/doltcore/sqle/clusterdb/database.go b/go/libraries/doltcore/sqle/clusterdb/database.go index 3240bc513c..5853d81be4 100644 --- a/go/libraries/doltcore/sqle/clusterdb/database.go +++ b/go/libraries/doltcore/sqle/clusterdb/database.go @@ -122,6 +122,10 @@ func (db database) RevisionQualifiedName() string { return db.Name() } +func (db database) RequestedName() string { + return db.Name() +} + type noopRepoStateWriter struct{} func (n noopRepoStateWriter) UpdateStagedRoot(ctx context.Context, newRoot *doltdb.RootValue) error { diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index ab9bbfdd2b..5534ef0b73 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -100,11 +100,6 @@ func (db Database) RevisionType() dsess.RevisionType { return db.revType } -// TODO: remove this -func (db Database) BaseName() string { - return db.name -} - func (db Database) EditOptions() editor.Options { return db.editOpts } @@ -155,6 +150,10 @@ func (db Database) RevisionQualifiedName() string { return db.name + dsess.DbRevisionDelimiter + db.revision } +func (db Database) RequestedName() string { + return db.requestedName +} + // GetDoltDB gets the underlying DoltDB of the Database func (db Database) GetDoltDB() *doltdb.DoltDB { return db.ddb diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index cb38e42e00..643d4736ae 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -725,17 +725,12 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual baseName, rev := parts[0], parts[1] p.mu.RLock() - candidate, ok := p.databases[formatDbMapKeyName(baseName)] + srcDb, ok := p.databases[formatDbMapKeyName(baseName)] p.mu.RUnlock() if !ok { return nil, false, nil } - srcDb, ok := candidate.(dsess.SqlDatabase) - if !ok { - return nil, false, nil - } - dbType, resolvedRevSpec, err := revisionDbType(ctx, srcDb, rev) if err != nil { return nil, false, err diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index a72ae334ea..5b01bb7ab8 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -68,6 +68,9 @@ type DatabaseSessionState struct { // currRevType is the current revision type of the database when referred to by its base name. Changes when a // `dolt_checkout` or `use` statement is executed. currRevType RevisionType + // checkedOutRevSpec is the checked out revision specifier of the database. Changes only when a `dolt_checkout` + // occurs. + checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState // globalState is the global state of this session (shared by all sessions for a particular db) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 8ec91acd64..a737c1c682 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -865,7 +865,6 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. } // SetCurrentHead sets the currently connected head revision spec for this session. -// TODO: more caveats and guidance func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref.WorkingSetRef) error { headRef, err := wsRef.ToHeadRef() if err != nil { @@ -873,17 +872,17 @@ func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref. } d.mu.Lock() + defer d.mu.Unlock() baseName, _ := SplitRevDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { - d.mu.Unlock() return sql.ErrDatabaseNotFound.New(dbName) } + + dbState.checkedOutRevSpec = headRef.GetPath() dbState.currRevSpec = headRef.GetPath() dbState.currRevType = RevisionTypeBranch - - d.mu.Unlock() return nil } @@ -945,8 +944,18 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { d.mu.Lock() defer d.mu.Unlock() - branchState.dbState.currRevSpec = sdb.Revision() - branchState.dbState.currRevType = sdb.RevisionType() + + // Set the session state for this database according to what database name was USEd + // In the case of a revision qualified name, that will be the revision specified + // In the case of an unqualified name (USE mydb), this will be the last checked out head in this session. + _, rev := SplitRevDbName(sdb.RequestedName()) + if rev == "" { + branchState.dbState.currRevSpec = branchState.dbState.checkedOutRevSpec + branchState.dbState.currRevType = RevisionTypeBranch + } else { + branchState.dbState.currRevSpec = sdb.Revision() + branchState.dbState.currRevType = sdb.RevisionType() + } return nil } diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index 59820e619b..8eb468766e 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -38,9 +38,12 @@ type RevisionDatabase interface { Revision() string // RevisionType returns the type of revision this database is pinned to. RevisionType() RevisionType - // RevisionQualiedName returns the fully qualified name of the database, which includes the revision if one is + // RevisionQualifiedName returns the fully qualified name of the database, which includes the revision if one is // specified. RevisionQualifiedName() string + // RequestedName returns the name of the database as requested by the user when the name was resolved to this + // database. + RequestedName() string } // RevisionType represents the type of revision a database is pinned to. For branches and tags, the revision is a diff --git a/go/libraries/doltcore/sqle/user_space_database.go b/go/libraries/doltcore/sqle/user_space_database.go index cb7bba625a..d4038b67e9 100644 --- a/go/libraries/doltcore/sqle/user_space_database.go +++ b/go/libraries/doltcore/sqle/user_space_database.go @@ -118,3 +118,7 @@ func (db *UserSpaceDatabase) RevisionType() dsess.RevisionType { func (db *UserSpaceDatabase) RevisionQualifiedName() string { return db.Name() } + +func (db *UserSpaceDatabase) RequestedName() string { + return db.Name() +} From 3ccea8cf431acd3c740e4f44f8ed3feb3031392b Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 16:26:12 -0700 Subject: [PATCH 040/167] Seems to all be working --- .../sqle/dsess/database_session_state.go | 7 +++---- go/libraries/doltcore/sqle/dsess/session.go | 16 ++++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 5b01bb7ab8..d777a773bf 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -58,10 +58,9 @@ type SessionDatabase interface { // DatabaseSessionState is the set of all information for a given database in this session. type DatabaseSessionState struct { - // dbName is the name of the database this state applies to. This includes a revision specifier in some cases. + // dbName is the name of the database this state applies to. This is always the base name of the database, without + // a revision qualifier. dbName string - // db is the database this state applies to - db SqlDatabase // currRevSpec is the current revision spec of the database when referred to by its base name. Changes when a // `dolt_checkout` or `use` statement is executed. currRevSpec string @@ -69,7 +68,7 @@ type DatabaseSessionState struct { // `dolt_checkout` or `use` statement is executed. currRevType RevisionType // checkedOutRevSpec is the checked out revision specifier of the database. Changes only when a `dolt_checkout` - // occurs. + // occurs. `USE mydb` without a revision qualifier will get this revision. checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index a737c1c682..da31b1b6c9 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -910,6 +910,7 @@ func (d *DoltSession) SwitchWorkingSet( d.mu.Unlock() return sql.ErrDatabaseNotFound.New(dbName) } + dbState.checkedOutRevSpec = headRef.GetPath() dbState.currRevSpec = headRef.GetPath() dbState.currRevType = RevisionTypeBranch @@ -949,12 +950,13 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { // In the case of a revision qualified name, that will be the revision specified // In the case of an unqualified name (USE mydb), this will be the last checked out head in this session. _, rev := SplitRevDbName(sdb.RequestedName()) + dbState := branchState.dbState if rev == "" { - branchState.dbState.currRevSpec = branchState.dbState.checkedOutRevSpec - branchState.dbState.currRevType = RevisionTypeBranch + dbState.currRevSpec = dbState.checkedOutRevSpec + dbState.currRevType = RevisionTypeBranch } else { - branchState.dbState.currRevSpec = sdb.Revision() - branchState.dbState.currRevType = sdb.RevisionType() + dbState.currRevSpec = sdb.Revision() + dbState.currRevType = sdb.RevisionType() } return nil @@ -1094,6 +1096,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } sessionState.dbName = baseName + sessionState.checkedOutRevSpec = db.Revision() sessionState.currRevType = db.RevisionType() sessionState.currRevSpec = db.Revision() } @@ -1101,10 +1104,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { branchState := NewEmptyBranchState(sessionState) sessionState.heads[strings.ToLower(rev)] = branchState d.mu.Unlock() - - // TODO: this doesn't seem right, shouldn't be a revision DB - sessionState.db = db - + // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and // the writer with one that errors out // TODO: this no longer gets called at session creation time, so the error handling below never occurs when a From f0b7363dfc22b9df67d810586990e27c68c65502 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 10 May 2023 16:42:44 -0700 Subject: [PATCH 041/167] Fixed an error with temp tables --- go/libraries/doltcore/sqle/database.go | 2 +- go/libraries/doltcore/sqle/dsess/session.go | 12 +- .../sqle/enginetest/dolt_engine_test.go | 115 +++++++----------- 3 files changed, 51 insertions(+), 78 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 5534ef0b73..6c5f9a9a47 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -187,7 +187,7 @@ func (db Database) GetTableInsensitive(ctx *sql.Context, tblName string) (sql.Ta // We start by first checking whether the input table is a temporary table. Temporary tables with name `x` take // priority over persisted tables of name `x`. ds := dsess.DSessFromSess(ctx.Session) - if tbl, ok := ds.GetTemporaryTable(ctx, db.RevisionQualifiedName(), tblName); ok { + if tbl, ok := ds.GetTemporaryTable(ctx, db.Name(), tblName); ok { return tbl, ok, nil } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index da31b1b6c9..bfe9de23bb 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1166,22 +1166,22 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } func (d *DoltSession) AddTemporaryTable(ctx *sql.Context, db string, tbl sql.Table) { - d.tempTables[db] = append(d.tempTables[db], tbl) + d.tempTables[strings.ToLower(db)] = append(d.tempTables[strings.ToLower(db)], tbl) } func (d *DoltSession) DropTemporaryTable(ctx *sql.Context, db, name string) { - tables := d.tempTables[db] - for i, tbl := range d.tempTables[db] { + tables := d.tempTables[strings.ToLower(db)] + for i, tbl := range d.tempTables[strings.ToLower(db)] { if strings.ToLower(tbl.Name()) == strings.ToLower(name) { tables = append(tables[:i], tables[i+1:]...) break } } - d.tempTables[db] = tables + d.tempTables[strings.ToLower(db)] = tables } func (d *DoltSession) GetTemporaryTable(ctx *sql.Context, db, name string) (sql.Table, bool) { - for _, tbl := range d.tempTables[db] { + for _, tbl := range d.tempTables[strings.ToLower(db)] { if strings.ToLower(tbl.Name()) == strings.ToLower(name) { return tbl, true } @@ -1191,7 +1191,7 @@ func (d *DoltSession) GetTemporaryTable(ctx *sql.Context, db, name string) (sql. // GetAllTemporaryTables returns all temp tables for this session. func (d *DoltSession) GetAllTemporaryTables(ctx *sql.Context, db string) ([]sql.Table, error) { - return d.tempTables[db], nil + return d.tempTables[strings.ToLower(db)], nil } // CWBHeadRef returns the branch ref for this session HEAD for the database named diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 1c45ece481..a9f9b13df3 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1513,7 +1513,7 @@ func installTestCommitClock(tcc *testCommitClock) func() { // TestSingleTransactionScript is a convenience method for debugging a single transaction test. Unskip and set to the // desired test. func TestSingleTransactionScript(t *testing.T) { - t.Skip() + // t.Skip() tcc := &testCommitClock{} cleanup := installTestCommitClock(tcc) @@ -1522,92 +1522,65 @@ func TestSingleTransactionScript(t *testing.T) { sql.RunWithNowFunc(tcc.Now, func() error { script := queries.TransactionTest{ - Name: "committed conflicts are seen by other sessions", + Name: "READ ONLY Transactions", SetUpScript: []string{ - "CREATE TABLE test (pk int primary key, val int)", - "CALL DOLT_ADD('.')", - "INSERT INTO test VALUES (0, 0)", - "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", - "CALL DOLT_CHECKOUT('-b', 'feature-branch')", - "INSERT INTO test VALUES (1, 1);", - "UPDATE test SET val=1000 WHERE pk=0;", - "CALL DOLT_COMMIT('-a', '-m', 'this is a normal commit');", - "CALL DOLT_CHECKOUT('main');", - "UPDATE test SET val=1001 WHERE pk=0;", - "CALL DOLT_COMMIT('-a', '-m', 'update a value');", + "create table t2 (pk int primary key, val int)", + "insert into t2 values (0,0)", + "commit", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "/* client a */ start transaction", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ start transaction", - Expected: []sql.Row{}, - }, - { - Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", - Expected: []sql.Row{{0, 1}}, - }, - { - Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{1}}, - }, - { - Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{0}}, - }, - { - Query: "/* client a */ set dolt_allow_commit_conflicts = 1", + Query: "/* client a */ set autocommit = off", Expected: []sql.Row{{}}, }, { - Query: "/* client a */ commit", + Query: "/* client a */ create temporary table tmp(pk int primary key)", + Expected: []sql.Row{{gmstypes.NewOkResult(0)}}, + }, + { + Query: "/* client a */ START TRANSACTION READ ONLY", Expected: []sql.Row{}, }, { - Query: "/* client b */ start transaction", + Query: "/* client a */ INSERT INTO tmp VALUES (1)", + Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, + }, + { + Query: "/* client a */ insert into t2 values (1, 1)", + ExpectedErr: sql.ErrReadOnlyTransaction, + }, + { + Query: "/* client a */ insert into t2 values (2, 2)", + ExpectedErr: sql.ErrReadOnlyTransaction, + }, + { + Query: "/* client a */ delete from t2 where pk = 0", + ExpectedErr: sql.ErrReadOnlyTransaction, + }, + { + + Query: "/* client a */ alter table t2 add val2 int", + Expected: []sql.Row{{gmstypes.NewOkResult(0)}}, + }, + { + Query: "/* client a */ select * from t2", + Expected: []sql.Row{{0, 0, nil}}, + }, + { + Query: "/* client a */ create temporary table tmp2(pk int primary key)", + ExpectedErr: sql.ErrReadOnlyTransaction, + }, + { + Query: "/* client a */ COMMIT", Expected: []sql.Row{}, }, { - Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{1}}, - }, - { - Query: "/* client a */ start transaction", + Query: "/* client b */ START TRANSACTION READ ONLY", Expected: []sql.Row{}, }, { - Query: "/* client a */ CALL DOLT_MERGE('--abort')", - Expected: []sql.Row{{0, 0}}, - }, - { - Query: "/* client a */ commit", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ start transaction", - Expected: []sql.Row{}, - }, - { - Query: "/* client a */ SET @@dolt_allow_commit_conflicts = 0", - Expected: []sql.Row{{}}, - }, - { - Query: "/* client a */ CALL DOLT_MERGE('feature-branch')", - ExpectedErrStr: dsess.ErrUnresolvedConflictsCommit.Error(), - }, - { // client rolled back on merge with conflicts - Query: "/* client a */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{0}}, - }, - { - Query: "/* client a */ commit", - Expected: []sql.Row{}, - }, - { - Query: "/* client b */ SELECT count(*) from dolt_conflicts_test", - Expected: []sql.Row{{0}}, + Query: "/* client b */ SELECT * FROM t2", + Expected: []sql.Row{{0, 0, nil}}, }, }, } From f09f2172edb9af5a9840be7345ed63e02da88003 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 11 May 2023 15:57:07 -0700 Subject: [PATCH 042/167] Fixed instances of GetHeadCommit --- go/libraries/doltcore/sqle/database.go | 14 +-- .../doltcore/sqle/dfunctions/hashof.go | 1 + .../doltcore/sqle/dolt_log_table_function.go | 2 +- .../doltcore/sqle/dtables/status_table.go | 6 +- .../sqle/enginetest/dolt_engine_test.go | 111 ++++++------------ go/libraries/doltcore/sqle/tables.go | 2 +- 6 files changed, 48 insertions(+), 88 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 6c5f9a9a47..6f11f9f361 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -266,7 +266,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds case strings.HasPrefix(lwrName, doltdb.DoltDiffTablePrefix): if head == nil { var err error - head, err = ds.GetHeadCommit(ctx, db.Name()) + head, err = ds.GetHeadCommit(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err @@ -300,7 +300,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds if head == nil { var err error - head, err = ds.GetHeadCommit(ctx, db.Name()) + head, err = ds.GetHeadCommit(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err } @@ -337,7 +337,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds case doltdb.LogTableName: if head == nil { var err error - head, err = ds.GetHeadCommit(ctx, db.Name()) + head, err = ds.GetHeadCommit(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err } @@ -357,7 +357,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds case doltdb.ColumnDiffTableName: if head == nil { var err error - head, err = ds.GetHeadCommit(ctx, db.Name()) + head, err = ds.GetHeadCommit(ctx, db.RevisionQualifiedName()) if err != nil { return nil, false, err } @@ -383,7 +383,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds case doltdb.StatusTableName: sess := dsess.DSessFromSess(ctx.Session) adapter := dsess.NewSessionStateAdapter( - sess, db.name, + sess, db.RevisionQualifiedName(), map[string]env.Remote{}, map[string]env.BranchConfig{}, map[string]env.Remote{}) @@ -391,7 +391,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds if err != nil { return nil, false, err } - dt, found = dtables.NewStatusTable(ctx, db.name, db.ddb, ws, adapter), true + dt, found = dtables.NewStatusTable(ctx, db.ddb, ws, adapter), true case doltdb.MergeStatusTableName: dt, found = dtables.NewMergeStatusTable(db.name), true case doltdb.TagsTableName: @@ -677,7 +677,7 @@ func (db Database) SetRoot(ctx *sql.Context, newRoot *doltdb.RootValue) error { // GetHeadRoot returns root value for the current session head func (db Database) GetHeadRoot(ctx *sql.Context) (*doltdb.RootValue, error) { sess := dsess.DSessFromSess(ctx.Session) - head, err := sess.GetHeadCommit(ctx, db.name) + head, err := sess.GetHeadCommit(ctx, db.RevisionQualifiedName()) if err != nil { return nil, err } diff --git a/go/libraries/doltcore/sqle/dfunctions/hashof.go b/go/libraries/doltcore/sqle/dfunctions/hashof.go index 296f39f7bd..2ab5b94425 100644 --- a/go/libraries/doltcore/sqle/dfunctions/hashof.go +++ b/go/libraries/doltcore/sqle/dfunctions/hashof.go @@ -74,6 +74,7 @@ func (t *HashOf) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { if strings.ToUpper(name) == "HEAD" { sess := dsess.DSessFromSess(ctx.Session) + // TODO: this should resolve the current DB through the analyzer so it can use the revision qualified name here cm, err = sess.GetHeadCommit(ctx, dbName) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/dolt_log_table_function.go b/go/libraries/doltcore/sqle/dolt_log_table_function.go index 103aafbfd0..0957083e78 100644 --- a/go/libraries/doltcore/sqle/dolt_log_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_log_table_function.go @@ -386,7 +386,7 @@ func (ltf *LogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter } } else { // If revisionExpr not defined, use session head - commit, err = sess.GetHeadCommit(ctx, sqledb.Name()) + commit, err = sess.GetHeadCommit(ctx, sqledb.RevisionQualifiedName()) if err != nil { return nil, err } diff --git a/go/libraries/doltcore/sqle/dtables/status_table.go b/go/libraries/doltcore/sqle/dtables/status_table.go index 50aa35d91b..fb6ccec869 100644 --- a/go/libraries/doltcore/sqle/dtables/status_table.go +++ b/go/libraries/doltcore/sqle/dtables/status_table.go @@ -32,7 +32,6 @@ type StatusTable struct { ddb *doltdb.DoltDB workingSet *doltdb.WorkingSet rootsProvider env.RootsProvider - dbName string } func (s StatusTable) Name() string { @@ -64,16 +63,15 @@ func (s StatusTable) PartitionRows(context *sql.Context, _ sql.Partition) (sql.R } // NewStatusTable creates a StatusTable -func NewStatusTable(_ *sql.Context, dbName string, ddb *doltdb.DoltDB, ws *doltdb.WorkingSet, rp env.RootsProvider) sql.Table { +func NewStatusTable(_ *sql.Context, ddb *doltdb.DoltDB, ws *doltdb.WorkingSet, rp env.RootsProvider) sql.Table { return &StatusTable{ ddb: ddb, - dbName: dbName, workingSet: ws, rootsProvider: rp, } } -// StatusIter is a sql.RowItr implementation which iterates over each commit as if it's a row in the table. +// StatusItr is a sql.RowIter implementation which iterates over each commit as if it's a row in the table. type StatusItr struct { rows []statusTableRow } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index a9f9b13df3..ad0533da06 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -118,91 +118,52 @@ func TestSingleScript(t *testing.T) { // t.Skip() var script = queries.ScriptTest{ - Name: "database revision specs: branch-qualified revision spec", + Name: "CALL DOLT_MERGE ff correctly works with autocommit off", SetUpScript: []string{ - "create table t01 (pk int primary key, c1 int)", - "call dolt_add('.')", - "call dolt_commit('-am', 'creating table t01 on main');", - "insert into t01 values (1, 1), (2, 2);", - "call dolt_commit('-am', 'adding rows to table t01 on main');", - "call dolt_branch('branch1');", - "insert into t01 values (3, 3);", - "call dolt_commit('-am', 'adding another row to table t01 on main');", + "CREATE TABLE test (pk int primary key)", + "call DOLT_ADD('.')", + "INSERT INTO test VALUES (0),(1),(2);", + "SET autocommit = 0", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", + "CALL DOLT_CHECKOUT('-b', 'feature-branch')", + "INSERT INTO test VALUES (3);", + "UPDATE test SET pk=1000 WHERE pk=0;", + "CALL DOLT_ADD('.');", + "CALL DOLT_COMMIT('-a', '-m', 'this is a ff');", + "CALL DOLT_CHECKOUT('main');", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "use mydb/branch1;", + // FF-Merge + Query: "CALL DOLT_MERGE('feature-branch')", + Expected: []sql.Row{{1, 0}}, + }, + { + Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", + Expected: []sql.Row{{false, nil, nil, nil}}, + }, + { + Query: "SELECT * from dolt_diff_test", + Expected: []sql.Row{ + sql.Row{0, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), interface {}(nil), "kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "added"}, + sql.Row{1, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), interface {}(nil), "kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "added"}, + sql.Row{2, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), interface {}(nil), "kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "added"}, + sql.Row{interface {}(nil), "WORKING", interface {}(nil), 0, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "removed"}, + sql.Row{3, "WORKING", interface {}(nil), interface {}(nil), "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "added"}, + sql.Row{1000, "WORKING", interface {}(nil), interface {}(nil), "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "added"}, + }, + }, + { + Query: "SELECT * from dolt_status", Expected: []sql.Row{}, }, { - Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, - }, - { - // The database name is always the base name, never the revision specifier - Query: "select database()", - Expected: []sql.Row{{"mydb"}}, - }, - { - Query: "select active_branch()", - Expected: []sql.Row{{"branch1"}}, - }, - { - Query: "select * from t01", - Expected: []sql.Row{{1, 1}, {2, 2}}, - }, - { - Query: "call dolt_checkout('main');", + Query: "CALL DOLT_CHECKOUT('-b', 'new-branch')", Expected: []sql.Row{{0}}, }, { - Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, - }, - { - Query: "select database();", - Expected: []sql.Row{{"mydb"}}, - }, - { - Query: "use mydb/branch1;", - Expected: []sql.Row{}, - }, - { - Query: "call dolt_reset();", - Expected: []sql.Row{{0}}, - }, - { - Query: "select database();", - Expected: []sql.Row{{"mydb"}}, - }, - { - Query: "show databases;", - Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, - }, - { - // Create a table in the working set to verify the main db - Query: "create table working_set_table(pk int primary key);", - Expected: []sql.Row{{gmstypes.NewOkResult(0)}}, - }, - { - Query: "select table_name from dolt_diff where commit_hash='WORKING';", - Expected: []sql.Row{{"working_set_table"}}, - }, - { - Query: "use mydb;", - Expected: []sql.Row{}, - }, - { - Query: "select table_name from dolt_diff where commit_hash='WORKING';", - Expected: []sql.Row{}, - }, - { - Query: "call dolt_checkout('branch1');", - Expected: []sql.Row{{0}}, - }, - { - Query: "select table_name from dolt_diff where commit_hash='WORKING';", - Expected: []sql.Row{{"working_set_table"}}, + Query: "INSERT INTO test VALUES (4)", + Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, }, }, } diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 889a9f2823..53e2683a6c 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -1258,7 +1258,7 @@ func (t *AlterableDoltTable) RewriteInserter( ws := dbState.WorkingSet() - head, err := sess.GetHeadCommit(ctx, t.db.Name()) + head, err := sess.GetHeadCommit(ctx, t.db.RevisionQualifiedName()) if err != nil { return nil, err } From 8a13712ba9e3ab44802b8ade016ed550b0ae6044 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 11 May 2023 16:12:02 -0700 Subject: [PATCH 043/167] Plugging in revision qualified names in more places --- go/libraries/doltcore/sqle/database.go | 8 ++++---- go/libraries/doltcore/sqle/dtables/ignore_table.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 6f11f9f361..75221eca95 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -363,13 +363,13 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds } } - dt, found = dtables.NewColumnDiffTable(ctx, db.name, db.ddb, head), true + dt, found = dtables.NewColumnDiffTable(ctx, db.RevisionQualifiedName(), db.ddb, head), true case doltdb.TableOfTablesInConflictName: - dt, found = dtables.NewTableOfTablesInConflict(ctx, db.name, db.ddb), true + dt, found = dtables.NewTableOfTablesInConflict(ctx, db.RevisionQualifiedName(), db.ddb), true case doltdb.TableOfTablesWithViolationsName: dt, found = dtables.NewTableOfTablesConstraintViolations(ctx, root), true case doltdb.SchemaConflictsTableName: - dt, found = dtables.NewSchemaConflictsTable(ctx, db.name, db.ddb), true + dt, found = dtables.NewSchemaConflictsTable(ctx, db.RevisionQualifiedName(), db.ddb), true case doltdb.BranchesTableName: dt, found = dtables.NewBranchesTable(ctx, db), true case doltdb.RemoteBranchesTableName: @@ -393,7 +393,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds } dt, found = dtables.NewStatusTable(ctx, db.ddb, ws, adapter), true case doltdb.MergeStatusTableName: - dt, found = dtables.NewMergeStatusTable(db.name), true + dt, found = dtables.NewMergeStatusTable(db.RevisionQualifiedName()), true case doltdb.TagsTableName: dt, found = dtables.NewTagsTable(ctx, db.ddb), true case dtables.AccessTableName: diff --git a/go/libraries/doltcore/sqle/dtables/ignore_table.go b/go/libraries/doltcore/sqle/dtables/ignore_table.go index 57e93201ed..152981dce6 100644 --- a/go/libraries/doltcore/sqle/dtables/ignore_table.go +++ b/go/libraries/doltcore/sqle/dtables/ignore_table.go @@ -160,6 +160,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { dbName := ctx.GetCurrentDatabase() dSess := dsess.DSessFromSess(ctx.Session) + // TODO: this needs to use a revision qualified name roots, _ := dSess.GetRoots(ctx, dbName) dbState, ok, err := dSess.LookupDbState(ctx, dbName) if err != nil { From dd9e393b0751fb4435f8771330f3463cf3c05407 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 11 May 2023 16:31:12 -0700 Subject: [PATCH 044/167] renamed receivers --- .../sqle/dsess/database_session_state.go | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index d777a773bf..90b8c0c026 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -131,39 +131,39 @@ func NewEmptyBranchState(dbState *DatabaseSessionState) *branchState { } } -func (d *branchState) WorkingRoot() *doltdb.RootValue { - return d.roots().Working +func (bs *branchState) WorkingRoot() *doltdb.RootValue { + return bs.roots().Working } var _ SessionState = (*branchState)(nil) -func (d *branchState) WorkingSet() *doltdb.WorkingSet { - return d.workingSet +func (bs *branchState) WorkingSet() *doltdb.WorkingSet { + return bs.workingSet } -func (d *branchState) WriteSession() writer.WriteSession { - return d.writeSession +func (bs *branchState) WriteSession() writer.WriteSession { + return bs.writeSession } -func (d *branchState) SessionCache() *SessionCache { - return d.sessionCache +func (bs *branchState) SessionCache() *SessionCache { + return bs.sessionCache } -func (d branchState) EditOpts() editor.Options { - return d.WriteSession().GetOptions() +func (bs branchState) EditOpts() editor.Options { + return bs.WriteSession().GetOptions() } -func (d *branchState) roots() doltdb.Roots { - if d.WorkingSet() == nil { +func (bs *branchState) roots() doltdb.Roots { + if bs.WorkingSet() == nil { return doltdb.Roots{ - Head: d.headRoot, - Working: d.headRoot, - Staged: d.headRoot, + Head: bs.headRoot, + Working: bs.headRoot, + Staged: bs.headRoot, } } return doltdb.Roots{ - Head: d.headRoot, - Working: d.WorkingSet().WorkingRoot(), - Staged: d.WorkingSet().StagedRoot(), + Head: bs.headRoot, + Working: bs.WorkingSet().WorkingRoot(), + Staged: bs.WorkingSet().StagedRoot(), } } From 818ac1e1f7475350fd6fe7235e312837f148b725 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 11 May 2023 16:55:23 -0700 Subject: [PATCH 045/167] Fixed compile error from merge --- go/libraries/doltcore/sqle/dsess/session.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index e5c8b15114..965a34afc9 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -570,7 +570,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do headCommit := branchState.headCommit headHash, _ := headCommit.HashOf() - if sessionState.WorkingSet == nil { + if branchState.WorkingSet() == nil { return nil, fmt.Errorf("Cannot commit while not attached to a branch. ") } From 9ee10c084ae5918c94a94eb98c63dca167c38b22 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 11 May 2023 17:30:54 -0700 Subject: [PATCH 046/167] Fix errors in merge --- go/libraries/doltcore/sqle/database_provider.go | 2 +- .../doltcore/sqle/dprocedures/dolt_merge.go | 9 +++++++++ go/libraries/doltcore/sqle/dsess/session.go | 12 ++++++------ .../doltcore/sqle/enginetest/dolt_engine_test.go | 13 +++---------- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 6a5f68c3ee..517674db18 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -607,7 +607,7 @@ func (p DoltDatabaseProvider) cloneDatabaseFromRemote( // DropDatabase implements the sql.MutableDatabaseProvider interface func (p DoltDatabaseProvider) DropDatabase(ctx *sql.Context, name string) error { - _, revision := dsess.SplitRevDbName(name) + _, revision := dsess.SplitRevisionDbName(name) if revision != "" { return fmt.Errorf("unable to drop revision database: %s", name) } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go index a098e288f4..1d03a04825 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go @@ -105,6 +105,9 @@ func doDoltMerge(ctx *sql.Context, args []string) (int, int, error) { if err != nil { return noConflictsOrViolations, threeWayMerge, err } + + // Because this commit happens outside the engine's control, we need to manually clear the transaction + ctx.SetTransaction(nil) return noConflictsOrViolations, threeWayMerge, nil } @@ -289,6 +292,9 @@ func executeFFMerge(ctx *sql.Context, dbName string, squash bool, ws *doltdb.Wor if err != nil { return ws, err } + + // because this commit happens outside the SQL engine's awareness, we need to manually clear the transaction + ctx.SetTransaction(nil) } return ws, nil @@ -344,6 +350,9 @@ func executeNoFFMerge( if err != nil { return nil, err } + + // because this commit happens outside the SQL engine's awareness, we need to manually clear the transaction + ctx.SetTransaction(nil) return ws, nil } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 965a34afc9..397c55b064 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -144,7 +144,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta dbName = strings.ToLower(dbName) var baseName, rev string - baseName, rev = SplitRevDbName(dbName) + baseName, rev = SplitRevisionDbName(dbName) d.mu.Lock() dbState, ok := d.dbStates[baseName] @@ -203,7 +203,7 @@ func revisionDbName(baseName string, rev string) string { return baseName + DbRevisionDelimiter + rev } -func SplitRevDbName(dbName string) (string, string) { +func SplitRevisionDbName(dbName string) (string, string) { var baseName, rev string parts := strings.SplitN(dbName, DbRevisionDelimiter, 2) baseName = parts[0] @@ -879,7 +879,7 @@ func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref. d.mu.Lock() defer d.mu.Unlock() - baseName, _ := SplitRevDbName(dbName) + baseName, _ := SplitRevisionDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { return sql.ErrDatabaseNotFound.New(dbName) @@ -909,7 +909,7 @@ func (d *DoltSession) SwitchWorkingSet( d.mu.Lock() - baseName, _ := SplitRevDbName(dbName) + baseName, _ := SplitRevisionDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { d.mu.Unlock() @@ -954,7 +954,7 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { // Set the session state for this database according to what database name was USEd // In the case of a revision qualified name, that will be the revision specified // In the case of an unqualified name (USE mydb), this will be the last checked out head in this session. - _, rev := SplitRevDbName(sdb.RequestedName()) + _, rev := SplitRevisionDbName(sdb.RequestedName()) dbState := branchState.dbState if rev == "" { dbState.currRevSpec = dbState.checkedOutRevSpec @@ -1222,7 +1222,7 @@ func (d *DoltSession) CurrentHead(ctx *sql.Context, dbName string) (string, bool dbName = strings.ToLower(dbName) var baseName, rev string - baseName, rev = SplitRevDbName(dbName) + baseName, rev = SplitRevisionDbName(dbName) if rev != "" { return "", false, fmt.Errorf("invalid database name: %s", dbName) } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index f11f035e8c..ba8ebc6612 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -115,7 +115,7 @@ func TestSingleQuery(t *testing.T) { // Convenience test for debugging a single query. Unskip and set to the desired query. func TestSingleScript(t *testing.T) { - // t.Skip() + t.Skip() var script = queries.ScriptTest{ Name: "CALL DOLT_MERGE ff correctly works with autocommit off", @@ -143,15 +143,8 @@ func TestSingleScript(t *testing.T) { Expected: []sql.Row{{false, nil, nil, nil}}, }, { - Query: "SELECT * from dolt_diff_test", - Expected: []sql.Row{ - sql.Row{0, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), interface {}(nil), "kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "added"}, - sql.Row{1, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), interface {}(nil), "kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "added"}, - sql.Row{2, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), interface {}(nil), "kcg4345ir3tjfb13mr0on1bv1m56h9if", time.Date(1970, time.January, 1, 4, 0, 0, 0, time.Local), "added"}, - sql.Row{interface {}(nil), "WORKING", interface {}(nil), 0, "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "removed"}, - sql.Row{3, "WORKING", interface {}(nil), interface {}(nil), "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "added"}, - sql.Row{1000, "WORKING", interface {}(nil), interface {}(nil), "bedi5n02gp5s9hukr79pirq3kbi6kh2r", time.Date(1970, time.January, 1, 11, 0, 0, 0, time.Local), "added"}, - }, + Query: "SELECT * from dolt_diff_test where to_commit = 'WORKING'", + Expected: []sql.Row{}, }, { Query: "SELECT * from dolt_status", From 3c53c5431d178580c224f38b597983683bb5ae40 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 16 May 2023 15:04:53 -0700 Subject: [PATCH 047/167] Couple small fixes --- .../binlog_replica_controller.go | 2 +- .../binlog_replica_filtering.go | 4 +- .../sqle/enginetest/dolt_engine_test.go | 48 +++++++++++++++---- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_controller.go b/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_controller.go index 8091650a69..f884d61453 100644 --- a/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_controller.go +++ b/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_controller.go @@ -443,7 +443,7 @@ func getOptionValueAsTableNames(option binlogreplication.ReplicationOption) ([]s func verifyAllTablesAreQualified(urts []sql.UnresolvedTable) error { for _, urt := range urts { - if urt.Database() == "" { + if urt.Database().Name() == "" { return fmt.Errorf("no database specified for table '%s'; "+ "all filter table names must be qualified with a database name", urt.Name()) } diff --git a/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_filtering.go b/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_filtering.go index 7ee5277b5c..5f115bc614 100644 --- a/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_filtering.go +++ b/go/libraries/doltcore/sqle/binlogreplication/binlog_replica_filtering.go @@ -59,7 +59,7 @@ func (fc *filterConfiguration) setDoTables(urts []sql.UnresolvedTable) error { for _, urt := range urts { table := strings.ToLower(urt.Name()) - db := strings.ToLower(urt.Database()) + db := strings.ToLower(urt.Database().Name()) if fc.doTables[db] == nil { fc.doTables[db] = make(map[string]struct{}) } @@ -86,7 +86,7 @@ func (fc *filterConfiguration) setIgnoreTables(urts []sql.UnresolvedTable) error for _, urt := range urts { table := strings.ToLower(urt.Name()) - db := strings.ToLower(urt.Database()) + db := strings.ToLower(urt.Database().Name()) if fc.ignoreTables[db] == nil { fc.ignoreTables[db] = make(map[string]struct{}) } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index ba8ebc6612..4c3a284a47 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -264,24 +264,52 @@ func TestSingleQueryPrepared(t *testing.T) { func TestSingleScriptPrepared(t *testing.T) { t.Skip() + var script = queries.ScriptTest{ - Name: "table with commit column should maintain its data in diff", + Name: "dolt_history table filter correctness", SetUpScript: []string{ - "CREATE TABLE t (pk int PRIMARY KEY, commit varchar(20));", - "CALL DOLT_ADD('.');", - "CALL dolt_commit('-am', 'creating table t');", - "INSERT INTO t VALUES (1, '123456');", - "CALL dolt_commit('-am', 'insert data');", + "create table xy (x int primary key, y int);", + "call dolt_add('.');", + "call dolt_commit('-m', 'creating table');", + "insert into xy values (0, 1);", + "call dolt_commit('-am', 'add data');", + "insert into xy values (2, 3);", + "call dolt_commit('-am', 'add data');", + "insert into xy values (4, 5);", + "call dolt_commit('-am', 'add data');", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "SELECT to_pk, char_length(to_commit), from_pk, char_length(from_commit), diff_type from dolt_diff_t;", - Expected: []sql.Row{{1, 32, nil, 32, "added"}}, + Query: "select * from dolt_history_xy where commit_hash = (select dolt_log.commit_hash from dolt_log limit 1 offset 1) order by 1", + Expected: []sql.Row{ + sql.Row{0, 1, "itt2nrlkbl7jis4gt9aov2l32ctt08th", "billy bob", time.Date(1970, time.January, 1, 19, 0, 0, 0, time.Local)}, + sql.Row{2, 3, "itt2nrlkbl7jis4gt9aov2l32ctt08th", "billy bob", time.Date(1970, time.January, 1, 19, 0, 0, 0, time.Local)}, + }, + }, + { + Query: "select count(*) from dolt_history_xy where commit_hash = (select dolt_log.commit_hash from dolt_log limit 1 offset 1)", + Expected: []sql.Row{ + {2}, + }, + }, + { + Query: "select count(*) from dolt_history_xy where commit_hash = 'itt2nrlkbl7jis4gt9aov2l32ctt08th'", + Expected: []sql.Row{ + {2}, + }, }, }, } - harness := newDoltHarness(t) - enginetest.TestScriptPrepared(t, harness, script) + + tcc := &testCommitClock{} + cleanup := installTestCommitClock(tcc) + defer cleanup() + + sql.RunWithNowFunc(tcc.Now, func() error { + harness := newDoltHarness(t) + enginetest.TestScriptPrepared(t, harness, script) + return nil + }) } func TestVersionedQueries(t *testing.T) { From 54451fb780d2176dd2f9a4b72deeedaa063aad71 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 16 May 2023 16:27:03 -0700 Subject: [PATCH 048/167] Fixing test --- go/libraries/doltcore/sqle/enginetest/dolt_server_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index c3922e04e7..45823e43b1 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -405,13 +405,15 @@ var DropDatabaseMultiSessionScriptTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - // At this point, this is an invalid revision database, and any queries against it will fail. Query: "/* client b */ select database();", - Expected: []sql.Row{{"db01/branch1"}}, + Expected: []sql.Row{{"db01"}}, }, + // TODO: this could be better: there's no longer a branch branch1, and we lose track of the fact that we were on + // branch1 when the `drop database` is processed -- as far as the engine is concerned we are using a database + // called `db01`, no branch info. It's enough for now to not panic in this edge case. { Query: "/* client b */ show tables;", - ExpectedErrStr: "Error 1105: database not found: db01/branch1", + Expected: []sql.Row{}, }, }, }, From a5e9685b6cf2000056b04424fd97df04b975e7e8 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 16 May 2023 17:07:51 -0700 Subject: [PATCH 049/167] Fixing more tests --- .../doltcore/sqle/database_provider.go | 5 ++-- go/libraries/doltcore/sqle/dsess/session.go | 1 - .../sqle/enginetest/dolt_server_test.go | 24 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 517674db18..211099e617 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -800,8 +800,9 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual } return db, true, nil case dsess.RevisionTypeNone: - // not an error, ok = false will get handled as a not found error in a layer above as appropriate - return nil, false, nil + // Returning an error with the fully qualified db name here is our only opportunity to do so in some cases (such + // as when a branch is deleted by another client) + return nil, false, sql.ErrDatabaseNotFound.New(revisionQualifiedName) default: return nil, false, fmt.Errorf("unrecognized revision type for revision spec %s", rev) } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 397c55b064..18c970ed3d 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -55,7 +55,6 @@ const ( var ErrWorkingSetChanges = goerrors.NewKind("Cannot switch working set, session state is dirty. " + "Rollback or commit changes before changing working sets.") var ErrSessionNotPeristable = errors.New("session is not persistable") -var ErrCurrentBranchDeleted = errors.New("current branch has been force deleted. run 'USE /' to checkout a different branch, or reconnect to the server") // DoltSession is the sql.Session implementation used by dolt. It is accessible through a *sql.Context instance type DoltSession struct { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index 45823e43b1..e465686ce0 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -121,7 +121,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt/branch1", "branch1"}}, + Expected: []sql.Row{{"dolt", "branch1"}}, }, { Query: "/* client b */ use dolt/branch2;", @@ -129,11 +129,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client b */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt/branch2", "branch2"}}, + Expected: []sql.Row{{"dolt", "branch2"}}, }, { Query: "/* client a */ SHOW DATABASES;", - Expected: []sql.Row{{"dolt"}, {"dolt/branch1"}, {"information_schema"}, {"mysql"}}, + Expected: []sql.Row{{"dolt"}, {"information_schema"}, {"mysql"}}, }, { Query: "/* client a */ CALL DOLT_BRANCH('-d', 'branch2');", @@ -145,7 +145,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ SHOW DATABASES;", - Expected: []sql.Row{{"dolt"}, {"dolt/branch1"}, {"information_schema"}, {"mysql"}}, + Expected: []sql.Row{{"dolt"}, {"information_schema"}, {"mysql"}}, }, { // Call a stored procedure since this searches across all databases and will @@ -168,7 +168,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt/branch1", "branch1"}}, + Expected: []sql.Row{{"dolt", "branch1"}}, }, { Query: "/* client b */ use dolt/branch2;", @@ -176,11 +176,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client b */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt/branch2", "branch2"}}, + Expected: []sql.Row{{"dolt", "branch2"}}, }, { Query: "/* client a */ SHOW DATABASES;", - Expected: []sql.Row{{"dolt"}, {"dolt/branch1"}, {"information_schema"}, {"mysql"}}, + Expected: []sql.Row{{"dolt"}, {"information_schema"}, {"mysql"}}, }, { Query: "/* client a */ CALL DOLT_BRANCH('-m', 'branch2', 'newName');", @@ -192,7 +192,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ SHOW DATABASES;", - Expected: []sql.Row{{"dolt"}, {"dolt/branch1"}, {"information_schema"}, {"mysql"}}, + Expected: []sql.Row{{"dolt"}, {"information_schema"}, {"mysql"}}, }, { // Call a stored procedure since this searches across all databases and will @@ -235,11 +235,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ select name from dolt_branches;", - ExpectedErrStr: "Error 1105: current branch has been force deleted. run 'USE /' to checkout a different branch, or reconnect to the server", + ExpectedErrStr: "Error 1105: database not found: dolt/branch1", }, { Query: "/* client a */ CALL DOLT_CHECKOUT('main');", - ExpectedErrStr: "Error 1105: current branch has been force deleted. run 'USE /' to checkout a different branch, or reconnect to the server", + ExpectedErrStr: "Error 1105: database not found: dolt/branch1", }, { Query: "/* client a */ USE dolt/main;", @@ -284,11 +284,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ select name from dolt_branches;", - ExpectedErrStr: "Error 1105: current branch has been force deleted. run 'USE /' to checkout a different branch, or reconnect to the server", + ExpectedErrStr: "Error 1105: database not found: dolt/branch1", }, { Query: "/* client a */ CALL DOLT_CHECKOUT('main');", - ExpectedErrStr: "Error 1105: current branch has been force deleted. run 'USE /' to checkout a different branch, or reconnect to the server", + ExpectedErrStr: "Error 1105: database not found: dolt/branch1", }, { Query: "/* client a */ USE dolt/main;", From 2ab5bf4f601d757ab0634869e37aec00b8ed86df Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 16 May 2023 17:30:38 -0700 Subject: [PATCH 050/167] Fixed merge tests --- .../sqle/enginetest/dolt_queries_merge.go | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index 7d6b761fd4..bf2694b3ab 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -209,8 +209,12 @@ var MergeScripts = []queries.ScriptTest{ Expected: []sql.Row{{"add some more values"}}, }, { - Query: "CALL DOLT_CHECKOUT('-b', 'other-branch')", - ExpectedErr: dsess.ErrWorkingSetChanges, + Query: "CALL DOLT_CHECKOUT('-b', 'other')", + Expected: []sql.Row{{0}}, + }, + { + Query: "CALL DOLT_CHECKOUT('main')", + Expected: []sql.Row{{0}}, }, }, }, @@ -251,10 +255,6 @@ var MergeScripts = []queries.ScriptTest{ Query: "select message from dolt_log where date < '2022-08-08' order by date DESC LIMIT 1;", Expected: []sql.Row{{"update a value"}}, }, - { - Query: "CALL DOLT_CHECKOUT('-b', 'other-branch')", - ExpectedErr: dsess.ErrWorkingSetChanges, - }, { Query: "SELECT COUNT(*) FROM dolt_conflicts", Expected: []sql.Row{{1}}, @@ -273,6 +273,38 @@ var MergeScripts = []queries.ScriptTest{ }, }, }, + { + Name: "merge conflicts prevent new branch creation", + SetUpScript: []string{ + "CREATE TABLE test (pk int primary key, val int)", + "call DOLT_ADD('.')", + "INSERT INTO test VALUES (0, 0)", + "SET autocommit = 0", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1', '--date', '2022-08-06T12:00:01');", + "CALL DOLT_CHECKOUT('-b', 'feature-branch')", + "INSERT INTO test VALUES (1, 1);", + "UPDATE test SET val=1000 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'this is a normal commit', '--date', '2022-08-06T12:00:02');", + "CALL DOLT_CHECKOUT('main');", + "UPDATE test SET val=1001 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'update a value', '--date', '2022-08-06T12:00:03');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "CALL DOLT_MERGE('feature-branch', '-m', 'this is a merge')", + Expected: []sql.Row{{0, 1}}, + }, + { + Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", + Expected: []sql.Row{{true, "feature-branch", "refs/heads/main", "test"}}, + }, + { + // errors because creating a new branch implicitly commits the current transaction + Query: "CALL DOLT_CHECKOUT('-b', 'other-branch')", + ExpectedErrStr: "Merge conflict detected, transaction rolled back. Merge conflicts must be resolved using the dolt_conflicts tables before committing a transaction. To commit transactions with merge conflicts, set @@dolt_allow_commit_conflicts = 1", + }, + }, + }, { Name: "CALL DOLT_MERGE ff & squash correctly works with autocommit off", SetUpScript: []string{ @@ -327,7 +359,11 @@ var MergeScripts = []queries.ScriptTest{ }, { Query: "CALL DOLT_CHECKOUT('-b', 'other')", - ExpectedErr: dsess.ErrWorkingSetChanges, + Expected: []sql.Row{{0}}, + }, + { + Query: "CALL DOLT_CHECKOUT('main')", + Expected: []sql.Row{{0}}, }, { Query: "SELECT * FROM test order by pk", From 93eadc677e01f139852dec55f2a160accf5f080d Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 16 May 2023 17:39:59 -0700 Subject: [PATCH 051/167] Added a dirty bit to branchState. Need to merge before I go any further --- go/libraries/doltcore/sqle/dsess/database_session_state.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 90b8c0c026..da32faa71e 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -122,6 +122,8 @@ type branchState struct { readOnly bool // sessionCache is a collection of cached values used to speed up performance sessionCache *SessionCache + // dirty is true if this branch state has uncommitted changes + dirty bool } func NewEmptyBranchState(dbState *DatabaseSessionState) *branchState { From aaccb5bd93d80a525467a1d5e1e0c7820a855257 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 16 May 2023 18:02:55 -0700 Subject: [PATCH 052/167] more tests of multi-branch transaction behavior --- .../sqle/enginetest/dolt_engine_test.go | 2 +- .../enginetest/dolt_transaction_queries.go | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 4c3a284a47..e2a6c9a5f6 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1137,7 +1137,7 @@ func TestBranchTransactions(t *testing.T) { } func TestMultiDbTransactions(t *testing.T) { - t.Skip() + // t.Skip() for _, script := range MultiDbTransactionTests { func() { h := newDoltHarness(t) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 8759096130..87306f0801 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2370,4 +2370,67 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to more than one branch at a time", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = 0", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into `mydb/b1`.t1 values (2)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into `mydb/b1`.t1 values (3)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "commit", + ExpectedErrStr: "cannot commit to more than one branch at once", + }, + }, + }, + { + Name: "committing to more than one database at a time", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "create database db2", + "set autocommit = 0", + "create table db2.t1 (a int)", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into db2.t1 values (2)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "commit", + ExpectedErrStr: "cannot commit to more than one database at once", + }, + }, + }, } From ae96ebc1f6d06bfda9eb83e10d29f3bf9c2ab776 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 17 May 2023 15:23:20 -0700 Subject: [PATCH 053/167] Updated dirty handling --- .../sqle/dsess/database_session_state.go | 3 +- go/libraries/doltcore/sqle/dsess/session.go | 43 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index da32faa71e..80c5f900c6 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -74,8 +74,6 @@ type DatabaseSessionState struct { heads map[string]*branchState // globalState is the global state of this session (shared by all sessions for a particular db) globalState globalstate.GlobalState - // dirty is true if this session has uncommitted changes - dirty bool // tmpFileDir is the directory to use for temporary files for this database tmpFileDir string @@ -123,6 +121,7 @@ type branchState struct { // sessionCache is a collection of cached values used to speed up performance sessionCache *SessionCache // dirty is true if this branch state has uncommitted changes + // TODO NEXT: fill this in and check it dirty bool } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 18c970ed3d..6b1d851107 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -402,21 +402,15 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er return nil } - isDirty, err := d.isDirty(ctx, dbName) - if err != nil { - return err + dirties := d.dirtyWorkingSets() + if len(dirties) == 0 { + return nil } - if !isDirty { - return nil + if len(dirties) > 1 { + return ErrDirtyWorkingSets } - - // This is triggered when certain commands are sent to the server (ex. commit) when a database is not selected. - // These commands should not error. - if dbName == "" { - return nil - } - + performDoltCommitVar, err := d.Session.GetSessionVariable(ctx, DoltCommitOnTransactionCommit) if err != nil { return err @@ -452,16 +446,20 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er } } -// isDirty returns whether the working set for the database named is dirty -// TODO: remove the dbname parameter, return a global dirty bit -// TODO: re-evaluate dirty tracking like this altogether, use tx data -func (d *DoltSession) isDirty(ctx *sql.Context, dbName string) (bool, error) { - branchState, _, err := d.lookupDbState(ctx, dbName) - if err != nil { - return false, err +var ErrDirtyWorkingSets = errors.New("multiple dirty working sets found") + +// dirtyWorkingSets returns all dirty working sets for this session +func (d *DoltSession) dirtyWorkingSets() []*branchState { + var dirtyStates []*branchState + for _, state := range d.dbStates { + for _, branchState := range state.heads { + if branchState.dirty { + dirtyStates = append(dirtyStates, branchState) + } + } } - return branchState.dbState.dirty, nil + return dirtyStates } // CommitWorkingSet commits the working set for the transaction given, without creating a new dolt commit. @@ -537,7 +535,7 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti return nil, err } - branchState.dbState.dirty = false + branchState.dirty = false return newCommit, nil } @@ -838,6 +836,7 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo // SetWorkingSet sets the working set for this session. // Unlike setting the working root alone, this method always marks the session dirty. // TODO: this is doing a lot of resolve work that should only happen once, at initialization time +// TODO: find uses of this for dirty changes func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb.WorkingSet) error { if ws == nil { panic("attempted to set a nil working set for the session") @@ -863,7 +862,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return err } - branchState.dbState.dirty = true + branchState.dirty = true return nil } From 2a4dd171668e30b3801494a89311e3145f4a0390 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 17 May 2023 18:28:01 -0700 Subject: [PATCH 054/167] Fixing NewPendingCommit --- go/libraries/doltcore/sqle/dsess/session.go | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 6b1d851107..2bca661968 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -411,6 +411,8 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er return ErrDirtyWorkingSets } + ws := dirties[0] + performDoltCommitVar, err := d.Session.GetSessionVariable(ctx, DoltCommitOnTransactionCommit) if err != nil { return err @@ -422,7 +424,7 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er } if peformDoltCommitInt == 1 { - pendingCommit, err := d.PendingCommitAllStaged(ctx, dbName, actions.CommitStagedProps{ + pendingCommit, err := d.PendingCommitAllStaged(ctx, ws, actions.CommitStagedProps{ Message: "Transaction commit", Date: ctx.QueryTime(), AllowEmpty: false, @@ -540,11 +542,8 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti } // PendingCommitAllStaged returns a pending commit with all tables staged. Returns nil if there are no changes to stage. -func (d *DoltSession) PendingCommitAllStaged(ctx *sql.Context, dbName string, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { - roots, ok := d.GetRoots(ctx, dbName) - if !ok { - return nil, fmt.Errorf("Couldn't get info for database %s", dbName) - } +func (d *DoltSession) PendingCommitAllStaged(ctx *sql.Context, branchState *branchState, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { + roots := branchState.roots() var err error roots, err = actions.StageAllTables(ctx, roots, true) @@ -552,18 +551,27 @@ func (d *DoltSession) PendingCommitAllStaged(ctx *sql.Context, dbName string, pr return nil, err } - return d.NewPendingCommit(ctx, dbName, roots, props) + return d.newPendingCommit(ctx, branchState, roots, props) } // NewPendingCommit returns a new |doltdb.PendingCommit| for the database named, using the roots given, adding any // merge parent from an in progress merge as appropriate. The session working set is not updated with these new roots, // but they are set in the returned |doltdb.PendingCommit|. If there are no changes staged, this method returns nil. func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots doltdb.Roots, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { - branchState, _, err := d.lookupDbState(ctx, dbName) + branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } + if !ok { + return nil, fmt.Errorf("session state for database %s not found", dbName) + } + + return d.newPendingCommit(ctx, branchState, roots, props) +} +// newPendingCommit returns a new |doltdb.PendingCommit| for the database and head named by |branchState| +// See NewPendingCommit +func (d *DoltSession) newPendingCommit(ctx *sql.Context, branchState *branchState, roots doltdb.Roots, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { headCommit := branchState.headCommit headHash, _ := headCommit.HashOf() @@ -591,7 +599,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do return nil, err } - err = d.SetWorkingSet(ctx, dbName, branchState.WorkingSet().WithStagedRoot(newRoots.Staged)) + err = d.SetWorkingSet(ctx, branchState.dbState.dbName, branchState.WorkingSet().WithStagedRoot(newRoots.Staged)) if err != nil { return nil, err } From 892ee845bb26f900334f1c5984373d2a6c849088 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 16:11:36 -0700 Subject: [PATCH 055/167] Finished logic to commit the dirty working set --- go/libraries/doltcore/sqle/dsess/session.go | 75 ++++++++++++--------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 2bca661968..ec60be9c91 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -386,15 +386,12 @@ func (d *DoltSession) newWorkingSetForHead(ctx *sql.Context, wsRef ref.WorkingSe // CommitTransaction commits the in-progress transaction for the database named. Depending on session settings, this // may write only a new working set, or may additionally create a new dolt commit for the current HEAD. func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) error { - dbName := ctx.GetTransactionDatabase() - if isNoOpTransactionDatabase(dbName) { - return nil - } - if d.BatchMode() == Batched { - err := d.Flush(ctx, dbName) - if err != nil { - return err + for _, db := range d.provider.DoltDatabases() { + err := d.Flush(ctx, db.Name()) + if err != nil { + return err + } } } @@ -411,8 +408,6 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er return ErrDirtyWorkingSets } - ws := dirties[0] - performDoltCommitVar, err := d.Session.GetSessionVariable(ctx, DoltCommitOnTransactionCommit) if err != nil { return err @@ -423,8 +418,9 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er return fmt.Errorf(fmt.Sprintf("Unexpected type for var %s: %T", DoltCommitOnTransactionCommit, performDoltCommitVar)) } + dirtyBranchState := dirties[0] if peformDoltCommitInt == 1 { - pendingCommit, err := d.PendingCommitAllStaged(ctx, ws, actions.CommitStagedProps{ + pendingCommit, err := d.PendingCommitAllStaged(ctx, dirtyBranchState, actions.CommitStagedProps{ Message: "Transaction commit", Date: ctx.QueryTime(), AllowEmpty: false, @@ -438,13 +434,13 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er // Nothing to stage, so fall back to CommitWorkingSet logic instead if pendingCommit == nil { - return d.CommitWorkingSet(ctx, dbName, tx) + return d.commitWorkingSet(ctx, dirtyBranchState, tx) } - _, err = d.DoltCommit(ctx, dbName, tx, pendingCommit) + _, err = d.DoltCommit(ctx, dirtyBranchState.dbState.dbName, tx, pendingCommit) return err } else { - return d.CommitWorkingSet(ctx, dbName, tx) + return d.commitWorkingSet(ctx, dirtyBranchState, tx) } } @@ -476,6 +472,16 @@ func (d *DoltSession) CommitWorkingSet(ctx *sql.Context, dbName string, tx sql.T return err } +func (d *DoltSession) commitWorkingSet(ctx *sql.Context, branchState *branchState, tx sql.Transaction) error { + commitFunc := func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, *doltdb.Commit, error) { + ws, err := dtx.Commit(ctx, workingSet, branchState.dbState.dbName) + return ws, nil, err + } + + _, err := d.doCommitInternal(ctx, branchState, tx, commitFunc) + return err +} + // DoltCommit commits the working set and a new dolt commit with the properties given. // Clients should typically use CommitTransaction, which performs additional checks, instead of this method. func (d *DoltSession) DoltCommit( @@ -509,6 +515,28 @@ func (d *DoltSession) DoltCommit( // updating HEAD with a new commit type doCommitFunc func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, *doltdb.Commit, error) +// doCommit exercise the business logic for a particular doCommitFunc +func (d *DoltSession) doCommitInternal(ctx *sql.Context, branchState *branchState, tx sql.Transaction, commitFunc doCommitFunc) (*doltdb.Commit, error) { + dtx, ok := tx.(*DoltTransaction) + if !ok { + return nil, fmt.Errorf("expected a DoltTransaction") + } + + mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, branchState.WorkingSet()) + if err != nil { + return nil, err + } + + // TODO: this is probably unnecessary + err = d.SetWorkingSet(ctx, branchState.dbState.dbName, mergedWorkingSet) + if err != nil { + return nil, err + } + + branchState.dirty = false + return newCommit, nil +} + // doCommit exercise the business logic for a particular doCommitFunc func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transaction, commitFunc doCommitFunc) (*doltdb.Commit, error) { branchState, ok, err := d.lookupDbState(ctx, dbName) @@ -521,24 +549,7 @@ func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transacti return nil, nil } - // TODO: validate that the transaction belongs to the DB named - dtx, ok := tx.(*DoltTransaction) - if !ok { - return nil, fmt.Errorf("expected a DoltTransaction") - } - - mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, branchState.WorkingSet()) - if err != nil { - return nil, err - } - - err = d.SetWorkingSet(ctx, dbName, mergedWorkingSet) - if err != nil { - return nil, err - } - - branchState.dirty = false - return newCommit, nil + return d.doCommitInternal(ctx, branchState, tx, commitFunc) } // PendingCommitAllStaged returns a pending commit with all tables staged. Returns nil if there are no changes to stage. From fadf6384e2fb5fe645e0741b4c89a6233eef60af Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 16:45:26 -0700 Subject: [PATCH 056/167] Nearly working --- go/libraries/doltcore/sqle/dsess/session.go | 20 ++++++++----------- go/libraries/doltcore/sqle/tables.go | 2 +- .../sqle/writer/noms_write_session.go | 1 + 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index ec60be9c91..59a355473b 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -522,17 +522,11 @@ func (d *DoltSession) doCommitInternal(ctx *sql.Context, branchState *branchStat return nil, fmt.Errorf("expected a DoltTransaction") } - mergedWorkingSet, newCommit, err := commitFunc(ctx, dtx, branchState.WorkingSet()) + _, newCommit, err := commitFunc(ctx, dtx, branchState.WorkingSet()) if err != nil { return nil, err } - - // TODO: this is probably unnecessary - err = d.SetWorkingSet(ctx, branchState.dbState.dbName, mergedWorkingSet) - if err != nil { - return nil, err - } - + branchState.dirty = false return newCommit, nil } @@ -1269,6 +1263,8 @@ func (d *DoltSession) BatchMode() batchMode { // setSessionVarsForDb updates the three session vars that track the value of the session root hashes func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state *branchState) error { + baseName, _ := SplitRevisionDbName(dbName) + // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here if state.WorkingSet() != nil { @@ -1277,7 +1273,7 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state return err } - err = d.Session.SetSessionVariable(ctx, HeadRefKey(dbName), headRef.String()) + err = d.Session.SetSessionVariable(ctx, HeadRefKey(baseName), headRef.String()) if err != nil { return err } @@ -1290,7 +1286,7 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state if err != nil { return err } - err = d.Session.SetSessionVariable(ctx, WorkingKey(dbName), h.String()) + err = d.Session.SetSessionVariable(ctx, WorkingKey(baseName), h.String()) if err != nil { return err } @@ -1301,7 +1297,7 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state if err != nil { return err } - err = d.Session.SetSessionVariable(ctx, StagedKey(dbName), h.String()) + err = d.Session.SetSessionVariable(ctx, StagedKey(baseName), h.String()) if err != nil { return err } @@ -1312,7 +1308,7 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state if err != nil { return err } - err = d.Session.SetSessionVariable(ctx, HeadKey(dbName), h.String()) + err = d.Session.SetSessionVariable(ctx, HeadKey(baseName), h.String()) if err != nil { return err } diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 66df550145..ba8854e03a 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -525,7 +525,7 @@ func (t *WritableDoltTable) getTableEditor(ctx *sql.Context) (ed writer.TableWri } setter := ds.SetRoot - ed, err = state.WriteSession().GetTableWriter(ctx, t.tableName, t.db.Name(), setter, batched) + ed, err = state.WriteSession().GetTableWriter(ctx, t.tableName, t.db.RevisionQualifiedName(), setter, batched) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/writer/noms_write_session.go b/go/libraries/doltcore/sqle/writer/noms_write_session.go index 763d29fd66..30ed68811c 100644 --- a/go/libraries/doltcore/sqle/writer/noms_write_session.go +++ b/go/libraries/doltcore/sqle/writer/noms_write_session.go @@ -34,6 +34,7 @@ import ( // It's responsible for creating and managing the lifecycle of TableWriter's. type WriteSession interface { // GetTableWriter creates a TableWriter and adds it to the WriteSession. + // TODO: track down refs to this, make sure they use the revision-qualified name GetTableWriter(ctx context.Context, table, db string, setter SessionRootSetter, batched bool) (TableWriter, error) // SetWorkingSet modifies the state of the WriteSession. The WorkingSetRef of |ws| must match the existing Ref. From 40c9b755a80e22f099e1887bf7c98f018169e204 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 17:08:48 -0700 Subject: [PATCH 057/167] we're so back --- go/libraries/doltcore/sqle/dsess/session.go | 2 +- .../doltcore/sqle/enginetest/dolt_transaction_queries.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 59a355473b..04f9090f07 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -444,7 +444,7 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er } } -var ErrDirtyWorkingSets = errors.New("multiple dirty working sets found") +var ErrDirtyWorkingSets = errors.New("Cannot commit changes on more than one branch / database") // dirtyWorkingSets returns all dirty working sets for this session func (d *DoltSession) dirtyWorkingSets() []*branchState { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 87306f0801..6a6819f5ee 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2400,7 +2400,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, { Query: "commit", - ExpectedErrStr: "cannot commit to more than one branch at once", + ExpectedErrStr: "Cannot commit changes on more than one branch / database", }, }, }, @@ -2429,7 +2429,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, { Query: "commit", - ExpectedErrStr: "cannot commit to more than one database at once", + ExpectedErrStr: "Cannot commit changes on more than one branch / database", }, }, }, From 9caafedf8ce9840f55abcfca7dca3fa84496386c Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 17:39:24 -0700 Subject: [PATCH 058/167] Moar tests --- .../enginetest/dolt_transaction_queries.go | 267 +++++++++++++++++- 1 file changed, 266 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 6a6819f5ee..84640289de 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2350,6 +2350,16 @@ var MultiDbTransactionTests = []queries.ScriptTest{ {types.OkResult{RowsAffected: 1}}, }, }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from `mydb/b1`.t1 order by a", + Expected: []sql.Row{ + {1}, {2}, + }, + }, { Query: "commit", Expected: []sql.Row{}, @@ -2370,6 +2380,235 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to another branch with autocommit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = on", // unnecessary but make it explicit + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `mydb/b1`.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{ + {1}, + }, + }, + }, + }, + { + Name: "checkout and use different branch", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = 0", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `mydb/b1`.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into `mydb/b1`.t1 values (2)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"b1"}}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{ + {1}, {2}, + }, + }, + { + Query: "call dolt_checkout('main')", + SkipResultsCheck: true, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "use `mydb/b1`", + Expected: []sql.Row{}, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"b1"}}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{{1}, {2}}, + }, + { + Query: "use mydb", + Expected: []sql.Row{}, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "commit", + Expected: []sql.Row{}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{ + {1}, {2}, + }, + }, + }, + }, + { + Name: "committing to another database", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "create database db1", + "use db1", + "create table t1 (a int)", + "use mydb", + "set autocommit = 0", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into db1.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into db1.t1 values (2)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from db1.t1 order by a", + Expected: []sql.Row{{1}, {2}}, + }, + { + Query: "commit", + Expected: []sql.Row{}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from db1.t1 order by a", + Expected: []sql.Row{{1}, {2}}, + }, + }, + }, + { + Name: "committing to another branch on another database", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "create database db1", + "use db1", + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "use mydb", + "set autocommit = 0", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `db1/b1`.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into `db1/b1`.t1 values (2)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from db1.t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from `db1/b1`.t1 order by a", + Expected: []sql.Row{{1}, {2}}, + }, + { + Query: "commit", + Expected: []sql.Row{}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from db1.t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from `db1/b1`.t1 order by a", + Expected: []sql.Row{{1}, {2}}, + }, + }, + }, { Name: "committing to more than one branch at a time", SetUpScript: []string{ @@ -2393,7 +2632,33 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "insert into `mydb/b1`.t1 values (3)", + Query: "commit", + ExpectedErrStr: "Cannot commit changes on more than one branch / database", + }, + }, + }, + { + Name: "committing to more than one branch at a time with checkout", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = 0", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "insert into t1 values (2)", Expected: []sql.Row{ {types.OkResult{RowsAffected: 1}}, }, From 2828ce6282b57924c10531a5b705dcbf5cf63bf2 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 18:15:32 -0700 Subject: [PATCH 059/167] unskip test --- go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index e2a6c9a5f6..92fdff9fbc 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1137,7 +1137,6 @@ func TestBranchTransactions(t *testing.T) { } func TestMultiDbTransactions(t *testing.T) { - // t.Skip() for _, script := range MultiDbTransactionTests { func() { h := newDoltHarness(t) From 1ea0961d9838c69393c216fce9be41a1b0e5ac6b Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 18:25:41 -0700 Subject: [PATCH 060/167] Fixed errors from main merge --- go/libraries/doltcore/sqle/database_provider.go | 5 ++++- go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go | 2 +- go/libraries/doltcore/sqle/dsess/session.go | 2 +- go/libraries/doltcore/sqle/dsess/transactions.go | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index a3c1f8755c..6b8a271efb 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1081,7 +1081,10 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds } if !ok { - headRef := db.DbData().Rsr.CWBHeadRef() + headRef, err := db.DbData().Rsr.CWBHeadRef() + if err != nil { + return nil, false, err + } head = headRef.GetPath() } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index f22f237fd5..7925533b6e 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -288,7 +288,7 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * // We need to commit the transaction here or else the branch we just created isn't visible to the current transaction, // and we are about to switch to it. So set the new branch head for the new transaction, then commit this one sess := dsess.DSessFromSess(ctx.Session) - err = commitTransaction(ctx, sess) + err = commitTransaction(ctx, sess, rsc) if err != nil { return err } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index ef93dd2c3c..6e8af7b9f7 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -818,7 +818,7 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R return err } - if sessionState.WorkingSet == nil { + if branchState.WorkingSet() == nil { return doltdb.ErrOperationNotSupportedInDetachedHead } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 8611792e57..f2d543ae2a 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -249,8 +249,8 @@ func txCommit(ctx *sql.Context, hash hash.Hash, // hash of the current working set to be written _ editor.Options, // editor options for merges ) (*doltdb.WorkingSet, *doltdb.Commit, error) { - err := doltDb.UpdateWorkingSet(ctx, workingSet.Ref(), workingSet, hash, tx.getWorkingSetMeta(ctx)) var rsc doltdb.ReplicationStatusController + err := doltDb.UpdateWorkingSet(ctx, workingSet.Ref(), workingSet, hash, tx.getWorkingSetMeta(ctx), &rsc) WaitForReplicationController(ctx, rsc) return workingSet, nil, err } From af1cb5157ed73db75edbad7cf8ffe07a6a7af91c Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 18:27:54 -0700 Subject: [PATCH 061/167] latest gms --- go/go.mod | 4 ++-- go/go.sum | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go/go.mod b/go/go.mod index 34ac1dad17..cde8ff990d 100644 --- a/go/go.mod +++ b/go/go.mod @@ -15,7 +15,7 @@ require ( github.com/dolthub/fslock v0.0.3 github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 - github.com/dolthub/vitess v0.0.0-20230508201056-fc3ee4c11ca5 + github.com/dolthub/vitess v0.0.0-20230518120917-a3e13f1a546a github.com/dustin/go-humanize v1.0.0 github.com/fatih/color v1.13.0 github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 @@ -59,7 +59,7 @@ require ( github.com/cespare/xxhash v1.1.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.15.1-0.20230517201855-8477b3b02370 + github.com/dolthub/go-mysql-server v0.15.1-0.20230519012556-81c365aafb54 github.com/dolthub/swiss v0.1.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/jmoiron/sqlx v1.3.4 diff --git a/go/go.sum b/go/go.sum index 2f7b1f7e2c..a6479acaa9 100644 --- a/go/go.sum +++ b/go/go.sum @@ -172,6 +172,8 @@ github.com/dolthub/go-mysql-server v0.15.1-0.20230517042856-2405a8d89854 h1:2AMV github.com/dolthub/go-mysql-server v0.15.1-0.20230517042856-2405a8d89854/go.mod h1:J+NMF5CgU6b3tBI4G2QVb1AUSf+YoPDDCsZkcM7rY1I= github.com/dolthub/go-mysql-server v0.15.1-0.20230517201855-8477b3b02370 h1:YGNpsPKq7u5cAow/5Sjb3ncu5Qh6SwCp5jBBMhtCnRs= github.com/dolthub/go-mysql-server v0.15.1-0.20230517201855-8477b3b02370/go.mod h1:J+NMF5CgU6b3tBI4G2QVb1AUSf+YoPDDCsZkcM7rY1I= +github.com/dolthub/go-mysql-server v0.15.1-0.20230519012556-81c365aafb54 h1:ZvK3NmxZbHr/DFxec3aF8KY+tahV72D1fZHm2p3cMxQ= +github.com/dolthub/go-mysql-server v0.15.1-0.20230519012556-81c365aafb54/go.mod h1:y9ZGm0yf/UFfztugI31qSLAcvG/BfmkVoffu+uv/0MY= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto= github.com/dolthub/jsonpath v0.0.1 h1:Nd+T3U+XisK3kOuxtABS5IIbZqXVIlOR9VYquyjQ0u0= @@ -184,6 +186,8 @@ 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-20230508201056-fc3ee4c11ca5 h1:Odi5ZtzgfS3B6MEwe5c5ADV70pjdnI3jbWr9XI5/vfg= github.com/dolthub/vitess v0.0.0-20230508201056-fc3ee4c11ca5/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= +github.com/dolthub/vitess v0.0.0-20230518120917-a3e13f1a546a h1:KnNvaz8GaUvMm+jvm11nGVlpR2lGaKQfWU4yaXLA4yg= +github.com/dolthub/vitess v0.0.0-20230518120917-a3e13f1a546a/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= From aec48f6ab742811ff19f2f23add2d4d3dbb4c9a0 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 18 May 2023 18:32:09 -0700 Subject: [PATCH 062/167] More errors from merge --- go/libraries/doltcore/sqle/database.go | 2 +- go/libraries/doltcore/sqle/dsess/session.go | 4 ++-- go/libraries/doltcore/sqle/dtables/ignore_table.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 69b9d83bdc..70d0e1ab97 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -673,7 +673,7 @@ func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) { if !ok { return nil, fmt.Errorf("no root value found in session") } - if dbState.WorkingSet == nil { + if dbState.WorkingSet() == nil { return nil, doltdb.ErrOperationNotSupportedInDetachedHead } return dbState.WorkingSet(), nil diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 6e8af7b9f7..4bd6075232 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -846,7 +846,7 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo return err } - if sessionState.WorkingSet == nil { + if sessionState.WorkingSet() == nil { return doltdb.ErrOperationNotSupportedInDetachedHead } @@ -992,7 +992,7 @@ func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.Worki if err != nil { return nil, err } - if sessionState.WorkingSet == nil { + if sessionState.WorkingSet() == nil { return nil, doltdb.ErrOperationNotSupportedInDetachedHead } return sessionState.WorkingSet(), nil diff --git a/go/libraries/doltcore/sqle/dtables/ignore_table.go b/go/libraries/doltcore/sqle/dtables/ignore_table.go index ba70ed0b5f..bc461f0fea 100644 --- a/go/libraries/doltcore/sqle/dtables/ignore_table.go +++ b/go/libraries/doltcore/sqle/dtables/ignore_table.go @@ -228,7 +228,7 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) { return } - if dbState.WorkingSet == nil { + if dbState.WorkingSet() == nil { iw.errDuringStatementBegin = doltdb.ErrOperationNotSupportedInDetachedHead return } From b4c7e26e04336140e5e7ad53af0708e40f562aba Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 19 May 2023 09:09:18 -0700 Subject: [PATCH 063/167] Add prepared test --- .../doltcore/sqle/enginetest/dolt_engine_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 92fdff9fbc..f37c28e9e0 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1146,6 +1146,16 @@ func TestMultiDbTransactions(t *testing.T) { } } +func TestMultiDbTransactionsPrepared(t *testing.T) { + for _, script := range MultiDbTransactionTests { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScriptPrepared(t, h, script) + }() + } +} + func TestConcurrentTransactions(t *testing.T) { h := newDoltHarness(t) defer h.Close() From a46ebe1f9ff7dd2c73ddeab381bb910793b402cc Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 19 May 2023 18:38:38 -0700 Subject: [PATCH 064/167] Added a debug port option to launch dlv, and fixed problems with graceful shutdown on windows --- .../dtestutils/sql_server_driver/cmd.go | 67 +++++++++++++++++-- .../sql_server_driver/cmd_windows.go | 50 ++------------ .../dtestutils/sql_server_driver/server.go | 4 ++ .../go-sql-server-driver/testdef.go | 12 +++- 4 files changed, 80 insertions(+), 53 deletions(-) mode change 100644 => 100755 go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go index 7572f79a89..d4e8972f44 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go @@ -25,12 +25,14 @@ import ( "os/exec" "path/filepath" "sync" + "syscall" "time" _ "github.com/go-sql-driver/mysql" ) var DoltPath string +var DelvePath string const TestUserName = "Bats Tests" const TestEmailAddress = "bats@email.fake" @@ -45,10 +47,13 @@ func init() { } path = filepath.Clean(path) var err error + DoltPath, err = exec.LookPath(path) if err != nil { log.Printf("did not find dolt binary: %v\n", err.Error()) } + + DelvePath, _ = exec.LookPath("dlv") } // DoltUser is an abstraction for a user account that calls `dolt` CLI @@ -66,8 +71,11 @@ type DoltUser struct { tmpdir string } +var _ DoltCmdable = DoltUser{} +var _ DoltDebuggable = DoltUser{} + func NewDoltUser() (DoltUser, error) { - tmpdir, err := os.MkdirTemp("", "go-sql-server-dirver-") + tmpdir, err := os.MkdirTemp("", "go-sql-server-driver-") if err != nil { return DoltUser{}, err } @@ -91,9 +99,33 @@ func (u DoltUser) DoltCmd(args ...string) *exec.Cmd { cmd := exec.Command(DoltPath, args...) cmd.Dir = u.tmpdir cmd.Env = append(os.Environ(), "DOLT_ROOT_PATH="+u.tmpdir) + // TODO: only on windows + cmd.SysProcAttr = &syscall.SysProcAttr{ + CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, + } return cmd } +func (u DoltUser) DoltDebug(debuggerPort int, args ...string) *exec.Cmd { + if DelvePath != "" { + dlvArgs := []string { + fmt.Sprintf("--listen=:%d", debuggerPort), + "--headless", + "--api-version=2", + "--accept-multiclient", + "exec", + DoltPath, + "--", + } + cmd := exec.Command(DelvePath, append(dlvArgs, args...)...) + cmd.Dir = u.tmpdir + cmd.Env = append(os.Environ(), "DOLT_ROOT_PATH="+u.tmpdir) + return cmd + } else { + panic("dlv not found") + } +} + func (u DoltUser) DoltExec(args ...string) error { cmd := u.DoltCmd(args...) return cmd.Run() @@ -116,6 +148,9 @@ type RepoStore struct { Dir string } +var _ DoltCmdable = RepoStore{} +var _ DoltDebuggable = RepoStore{} + func (rs RepoStore) MakeRepo(name string) (Repo, error) { path := filepath.Join(rs.Dir, name) err := os.Mkdir(path, 0750) @@ -136,6 +171,12 @@ func (rs RepoStore) DoltCmd(args ...string) *exec.Cmd { return cmd } +func (rs RepoStore) DoltDebug(debuggerPort int, args ...string) *exec.Cmd { + cmd := rs.user.DoltDebug(debuggerPort, args...) + cmd.Dir = rs.Dir + return cmd +} + type Repo struct { user DoltUser Dir string @@ -191,11 +232,29 @@ func WithPort(port int) SqlServerOpt { } type DoltCmdable interface { - DoltCmd(...string) *exec.Cmd + DoltCmd(args ...string) *exec.Cmd +} + +type DoltDebuggable interface { + DoltDebug(debuggerPort int, args ...string) *exec.Cmd } func StartSqlServer(dc DoltCmdable, opts ...SqlServerOpt) (*SqlServer, error) { cmd := dc.DoltCmd("sql-server") + return runSqlServerCommand(dc, opts, cmd) +} + +func DebugSqlServer(dc DoltCmdable, debuggerPort int, opts ...SqlServerOpt) (*SqlServer, error) { + ddb, ok := dc.(DoltDebuggable) + if !ok { + return nil, fmt.Errorf("%T does not implement DoltDebuggable", dc) + } + + cmd := ddb.DoltDebug(debuggerPort, "sql-server") + return runSqlServerCommand(dc, opts, cmd) +} + +func runSqlServerCommand(dc DoltCmdable, opts []SqlServerOpt, cmd *exec.Cmd) (*SqlServer, error) { stdout, err := cmd.StdoutPipe() if err != nil { return nil, err @@ -232,10 +291,6 @@ func StartSqlServer(dc DoltCmdable, opts ...SqlServerOpt) (*SqlServer, error) { return ret, nil } -func (r Repo) StartSqlServer(opts ...SqlServerOpt) (*SqlServer, error) { - return StartSqlServer(r, opts...) -} - func (s *SqlServer) ErrorStop() error { <-s.Done return s.Cmd.Wait() diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go old mode 100644 new mode 100755 index b365f0e972..eca76c9400 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go @@ -15,61 +15,21 @@ package sql_server_driver import ( - "syscall" - "golang.org/x/sys/windows" ) func (s *SqlServer) GracefulStop() error { - dll, err := windows.LoadDLL("kernel32.dll") + err := windows.GenerateConsoleCtrlEvent(windows.CTRL_BREAK_EVENT, uint32(s.Cmd.Process.Pid)) if err != nil { return err } - defer dll.Release() - - pid := s.Cmd.Process.Pid - - f, err := dll.FindProc("AttachConsole") - if err != nil { - return err - } - r1, _, err := f.Call(uintptr(pid)) - if r1 == 0 && err != syscall.ERROR_ACCESS_DENIED { - return err - } - - set, err := dll.FindProc("SetConsoleCtrlHandler") - if err != nil { - return err - } - r1, _, err = set.Call(0, 1) - if r1 == 0 { - return err - } - f, err = dll.FindProc("GenerateConsoleCtrlEvent") - if err != nil { - return err - } - r1, _, err = f.Call(windows.CTRL_BREAK_EVENT, uintptr(pid)) - if r1 == 0 { - return err - } - - f, err = dll.FindProc("FreeConsole") - if err != nil { - return err - } - _, _, err = f.Call() - if err != nil { - return err - } - + <-s.Done - r1, _, err = set.Call(0, 0) - if r1 == 0 { + _, err = s.Cmd.Process.Wait() + if err != nil { return err } - return s.Cmd.Wait() + return nil } diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/server.go b/go/libraries/doltcore/dtestutils/sql_server_driver/server.go index 766e117476..8f64f69973 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/server.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/server.go @@ -162,6 +162,10 @@ type Server struct { // the |Args| to make sure this is true. Defaults to 3308. Port int `yaml:"port"` + // DebugPort if set to a non-zero value will cause this server to be started with |dlv| listening for a debugger + // connection on the port given. + DebugPort int `yaml:"debug_port"` + // Assertions to be run against the log output of the server process // after the server process successfully terminates. LogMatches []string `yaml:"log_matches"` diff --git a/integration-tests/go-sql-server-driver/testdef.go b/integration-tests/go-sql-server-driver/testdef.go index e0ff885098..5cd47c336e 100644 --- a/integration-tests/go-sql-server-driver/testdef.go +++ b/integration-tests/go-sql-server-driver/testdef.go @@ -22,7 +22,7 @@ import ( "time" "database/sql" - + driver "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils/sql_server_driver" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -78,7 +78,15 @@ func MakeServer(t *testing.T, dc driver.DoltCmdable, s *driver.Server) *driver.S if s.Port != 0 { opts = append(opts, driver.WithPort(s.Port)) } - server, err := driver.StartSqlServer(dc, opts...) + + var server *driver.SqlServer + var err error + if s.DebugPort != 0 { + server, err = driver.DebugSqlServer(dc, s.DebugPort, opts...) + } else { + server, err = driver.StartSqlServer(dc, opts...) + } + require.NoError(t, err) if len(s.ErrorMatches) > 0 { err := server.ErrorStop() From 6552385c17104f74cc5d82603e9570e0830f10ef Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 09:29:56 -0700 Subject: [PATCH 065/167] Fixes for windows process signalling --- .../doltcore/dtestutils/sql_server_driver/cmd.go | 6 +----- .../doltcore/dtestutils/sql_server_driver/cmd_unix.go | 4 ++++ .../dtestutils/sql_server_driver/cmd_windows.go | 11 +++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go index d4e8972f44..59d7873660 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go @@ -25,7 +25,6 @@ import ( "os/exec" "path/filepath" "sync" - "syscall" "time" _ "github.com/go-sql-driver/mysql" @@ -99,10 +98,7 @@ func (u DoltUser) DoltCmd(args ...string) *exec.Cmd { cmd := exec.Command(DoltPath, args...) cmd.Dir = u.tmpdir cmd.Env = append(os.Environ(), "DOLT_ROOT_PATH="+u.tmpdir) - // TODO: only on windows - cmd.SysProcAttr = &syscall.SysProcAttr{ - CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, - } + ApplyCmdAttributes(cmd) return cmd } diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go index b8b6ed6973..d8f43f9e9d 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go @@ -19,6 +19,10 @@ package sql_server_driver import "syscall" +func ApplyCmdAttributes(cmd *exec.Cmd) { + // nothing to do on unix / darwin +} + func (s *SqlServer) GracefulStop() error { err := s.Cmd.Process.Signal(syscall.SIGTERM) if err != nil { diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go index eca76c9400..451a0970ec 100755 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go @@ -15,9 +15,20 @@ package sql_server_driver import ( + "os/exec" + "syscall" + "golang.org/x/sys/windows" ) +func ApplyCmdAttributes(cmd *exec.Cmd) { + // Creating a new process group for the process will allow GracefulStop to send the break signal to that process + // without also killing the parent process + cmd.SysProcAttr = &syscall.SysProcAttr{ + CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, + } +} + func (s *SqlServer) GracefulStop() error { err := windows.GenerateConsoleCtrlEvent(windows.CTRL_BREAK_EVENT, uint32(s.Cmd.Process.Pid)) if err != nil { From ae2b616add668f4926dadcaa5f1012889e77c5af Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 11:41:27 -0700 Subject: [PATCH 066/167] Added debug timeouts and a run single test method --- .../go-sql-server-driver/main_test.go | 4 +++ .../go-sql-server-driver/testdef.go | 25 +++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/integration-tests/go-sql-server-driver/main_test.go b/integration-tests/go-sql-server-driver/main_test.go index cf89dd562c..44a5c07cc4 100644 --- a/integration-tests/go-sql-server-driver/main_test.go +++ b/integration-tests/go-sql-server-driver/main_test.go @@ -28,6 +28,10 @@ func TestCluster(t *testing.T) { RunTestsFile(t, "tests/sql-server-cluster.yaml") } +func TestSingle(t *testing.T) { + RunSingleTest(t, "tests/sql-server-cluster.yaml", "primary comes up and replicates to standby") +} + func TestClusterTLS(t *testing.T) { RunTestsFile(t, "tests/sql-server-cluster-tls.yaml") } diff --git a/integration-tests/go-sql-server-driver/testdef.go b/integration-tests/go-sql-server-driver/testdef.go index 5cd47c336e..aa93b8b277 100644 --- a/integration-tests/go-sql-server-driver/testdef.go +++ b/integration-tests/go-sql-server-driver/testdef.go @@ -46,6 +46,17 @@ type Test struct { Skip string `yaml:"skip"` } +// Set this environment variable to effectively disable timeouts for debugging. +const debugEnvKey = "DOLT_SQL_SERVER_TEST_DEBUG" +var timeout = 20 * time.Second + +func init() { + _, ok := os.LookupEnv(debugEnvKey) + if ok { + timeout = 1000 * time.Hour + } +} + func ParseTestsFile(path string) (TestDef, error) { contents, err := os.ReadFile(path) if err != nil { @@ -206,6 +217,16 @@ func RunTestsFile(t *testing.T, path string) { } } +func RunSingleTest(t *testing.T, path string, testName string) { + def, err := ParseTestsFile(path) + require.NoError(t, err) + for _, test := range def.Tests { + if test.Name == testName { + t.Run(test.Name, test.Run) + } + } +} + type retryTestingT struct { *testing.T errorfStrings []string @@ -276,7 +297,7 @@ func RunQueryAttempt(t require.TestingT, conn *sql.Conn, q driver.Query) { args[i] = q.Args[i] } if q.Query != "" { - ctx, c := context.WithTimeout(context.Background(), 20*time.Second) + ctx, c := context.WithTimeout(context.Background(), timeout) defer c() rows, err := conn.QueryContext(ctx, q.Query, args...) if err == nil { @@ -299,7 +320,7 @@ func RunQueryAttempt(t require.TestingT, conn *sql.Conn, q driver.Query) { require.Contains(t, *q.Result.Rows.Or, rowstrings) } } else if q.Exec != "" { - ctx, c := context.WithTimeout(context.Background(), 20*time.Second) + ctx, c := context.WithTimeout(context.Background(), timeout) defer c() _, err := conn.ExecContext(ctx, q.Exec, args...) if q.ErrorMatch == "" { From 5a507edda106826e14601a8cda6faf4f8d48d5b4 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 11:42:00 -0700 Subject: [PATCH 067/167] Debug options for sql server tests --- .../dtestutils/sql_server_driver/cmd.go | 35 ++++++++++++++----- .../doltcore/sqle/clusterdb/database.go | 8 +---- .../doltcore/sqle/database_provider.go | 3 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go index 59d7873660..bf39d66f49 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go @@ -116,6 +116,7 @@ func (u DoltUser) DoltDebug(debuggerPort int, args ...string) *exec.Cmd { cmd := exec.Command(DelvePath, append(dlvArgs, args...)...) cmd.Dir = u.tmpdir cmd.Env = append(os.Environ(), "DOLT_ROOT_PATH="+u.tmpdir) + ApplyCmdAttributes(cmd) return cmd } else { panic("dlv not found") @@ -202,6 +203,7 @@ type SqlServer struct { Done chan struct{} Cmd *exec.Cmd Port int + DebugPort int Output *bytes.Buffer DBName string RecreateCmd func(args ...string) *exec.Cmd @@ -227,6 +229,12 @@ func WithPort(port int) SqlServerOpt { } } +func WithDebugPort(port int) SqlServerOpt { + return func(s *SqlServer) { + s.DebugPort = port + } +} + type DoltCmdable interface { DoltCmd(args ...string) *exec.Cmd } @@ -247,7 +255,7 @@ func DebugSqlServer(dc DoltCmdable, debuggerPort int, opts ...SqlServerOpt) (*Sq } cmd := ddb.DoltDebug(debuggerPort, "sql-server") - return runSqlServerCommand(dc, opts, cmd) + return runSqlServerCommand(dc, append(opts, WithDebugPort(debuggerPort)), cmd) } func runSqlServerCommand(dc DoltCmdable, opts []SqlServerOpt, cmd *exec.Cmd) (*SqlServer, error) { @@ -268,23 +276,34 @@ func runSqlServerCommand(dc DoltCmdable, opts []SqlServerOpt, cmd *exec.Cmd) (*S wg.Wait() close(done) }() - ret := &SqlServer{ + + server := &SqlServer{ Done: done, Cmd: cmd, Port: 3306, Output: output, - RecreateCmd: func(args ...string) *exec.Cmd { - return dc.DoltCmd(args...) - }, } for _, o := range opts { - o(ret) + o(server) } - err = ret.Cmd.Start() + + server.RecreateCmd = func(args ...string) *exec.Cmd { + if server.DebugPort > 0 { + ddb, ok := dc.(DoltDebuggable) + if !ok { + panic(fmt.Sprintf("%T does not implement DoltDebuggable", dc)) + } + return ddb.DoltDebug(server.DebugPort, args...) + } else { + return dc.DoltCmd(args...) + } + } + + err = server.Cmd.Start() if err != nil { return nil, err } - return ret, nil + return server, nil } func (s *SqlServer) ErrorStop() error { diff --git a/go/libraries/doltcore/sqle/clusterdb/database.go b/go/libraries/doltcore/sqle/clusterdb/database.go index 45e5447abe..c631816f42 100644 --- a/go/libraries/doltcore/sqle/clusterdb/database.go +++ b/go/libraries/doltcore/sqle/clusterdb/database.go @@ -146,13 +146,7 @@ func (db database) RequestedName() string { type noopRepoStateWriter struct{} -func (n noopRepoStateWriter) UpdateStagedRoot(ctx context.Context, newRoot *doltdb.RootValue) error { - return nil -} - -func (n noopRepoStateWriter) UpdateWorkingRoot(ctx context.Context, newRoot *doltdb.RootValue) error { - return nil -} +var _ env.RepoStateWriter = noopRepoStateWriter{} func (n noopRepoStateWriter) SetCWBHeadRef(ctx context.Context, marshalableRef ref.MarshalableRef) error { return nil diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 6b8a271efb..c47addd218 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1081,7 +1081,8 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds } if !ok { - headRef, err := db.DbData().Rsr.CWBHeadRef() + rsr := db.DbData().Rsr + headRef, err := rsr.CWBHeadRef() if err != nil { return nil, false, err } From bd952a07cf723ef6e92dc0fb2c71540b7ea297bb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 13:11:44 -0700 Subject: [PATCH 068/167] Fixed panic for databases that cannot support revisions --- .../doltcore/sqle/clusterdb/database.go | 4 ++++ go/libraries/doltcore/sqle/database.go | 4 ++++ .../doltcore/sqle/database_provider.go | 23 +++++++++++-------- .../sqle/dsess/session_db_provider.go | 5 ++++ .../doltcore/sqle/user_space_database.go | 4 ++++ 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/clusterdb/database.go b/go/libraries/doltcore/sqle/clusterdb/database.go index c631816f42..8469c30ea1 100644 --- a/go/libraries/doltcore/sqle/clusterdb/database.go +++ b/go/libraries/doltcore/sqle/clusterdb/database.go @@ -132,6 +132,10 @@ func (db database) Revision() string { return "" } +func (db database) Versioned() bool { + return false +} + func (db database) RevisionType() dsess.RevisionType { return dsess.RevisionTypeNone } diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 70d0e1ab97..dd013a3d7d 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -96,6 +96,10 @@ func (db Database) Revision() string { return db.revision } +func (db Database) Versioned() bool { + return true +} + func (db Database) RevisionType() dsess.RevisionType { return db.revType } diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index c47addd218..a72acae7f2 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1038,9 +1038,9 @@ func resolveAncestorSpec(ctx *sql.Context, revSpec string, ddb *doltdb.DoltDB) ( // SessionDatabase implements dsess.SessionDatabaseProvider func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (dsess.SqlDatabase, bool, error) { baseName := name - isRevisionDb := strings.Contains(name, dsess.DbRevisionDelimiter) + isRevisionDbName := strings.Contains(name, dsess.DbRevisionDelimiter) - if isRevisionDb { + if isRevisionDbName { // TODO: formalize and enforce this rule (can't allow DBs with / in the name) // TODO: some connectors will take issue with the /, we need other mechanisms to support them parts := strings.SplitN(name, dsess.DbRevisionDelimiter, 2) @@ -1066,15 +1066,20 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds return nil, false, nil } } + + // Some DB implementations don't support addressing by versioned names, so return directly if we have one of those + if !db.Versioned() { + return wrapForStandby(db, standby), true, nil + } - // The db map only contains base databases, not revision DBs. Convert to a revision DB for creation. + // Convert to a revision database before returning. If we got a non-qualified name, convert it to a qualified name + // using the session's current head revisionQualifiedName := name - if !isRevisionDb { + if !isRevisionDbName { sess := dsess.DSessFromSess(ctx.Session) - // To find the correct revision DB for this unqualified name, we need to look into the session state. A newly - // created session may not have any info on current head stored yet, in which case we get the default branch for - // the db itself instead. + // A newly created session may not have any info on current head stored yet, in which case we get the default + // branch for the db itself instead. head, ok, err := sess.CurrentHead(ctx, baseName) if err != nil { return nil, false, err @@ -1091,7 +1096,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds revisionQualifiedName = baseName + dsess.DbRevisionDelimiter + head } - + db, ok, err := p.databaseForRevision(ctx, revisionQualifiedName, name) if err != nil { return nil, false, err @@ -1099,7 +1104,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds if !ok { return nil, false, nil } - + return wrapForStandby(db, standby), true, nil } diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index 8eb468766e..f575598666 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -44,6 +44,11 @@ type RevisionDatabase interface { // RequestedName returns the name of the database as requested by the user when the name was resolved to this // database. RequestedName() string + // Versioned returns whether this database implementation supports more than a single revision. + // TODO: This shouldn't be a necessary part of the interface, but it's required to differentiate between dolt-backed + // databases and others that we serve for custom purposes with similar pieces of functionality, and the session + // management logic intermixes these concerns. + Versioned() bool } // RevisionType represents the type of revision a database is pinned to. For branches and tags, the revision is a diff --git a/go/libraries/doltcore/sqle/user_space_database.go b/go/libraries/doltcore/sqle/user_space_database.go index d4038b67e9..6c34dd2d50 100644 --- a/go/libraries/doltcore/sqle/user_space_database.go +++ b/go/libraries/doltcore/sqle/user_space_database.go @@ -111,6 +111,10 @@ func (db *UserSpaceDatabase) Revision() string { return "" } +func (db *UserSpaceDatabase) Versioned() bool { + return false +} + func (db *UserSpaceDatabase) RevisionType() dsess.RevisionType { return dsess.RevisionTypeNone } From 9b2cd87c578e0ec0ffe4bfe10e772a1f57f5a75c Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 13:49:32 -0700 Subject: [PATCH 069/167] Added a README --- .../go-sql-server-driver/main_test.go | 3 + .../go-sql-server-driver/tests/README.md | 78 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 integration-tests/go-sql-server-driver/tests/README.md diff --git a/integration-tests/go-sql-server-driver/main_test.go b/integration-tests/go-sql-server-driver/main_test.go index 44a5c07cc4..f81d6084ab 100644 --- a/integration-tests/go-sql-server-driver/main_test.go +++ b/integration-tests/go-sql-server-driver/main_test.go @@ -28,7 +28,10 @@ func TestCluster(t *testing.T) { RunTestsFile(t, "tests/sql-server-cluster.yaml") } +// TestSingle is a convenience method for running a single test from within an IDE. Unskip and set to the file and name +// of the test you want to debug. See README.md in the `tests` directory for more debugging info. func TestSingle(t *testing.T) { + // t.Skip() RunSingleTest(t, "tests/sql-server-cluster.yaml", "primary comes up and replicates to standby") } diff --git a/integration-tests/go-sql-server-driver/tests/README.md b/integration-tests/go-sql-server-driver/tests/README.md new file mode 100644 index 0000000000..a4f2776c74 --- /dev/null +++ b/integration-tests/go-sql-server-driver/tests/README.md @@ -0,0 +1,78 @@ +# SQL server tests + +These are the definitions for tests that spin up multiple sql-server instances +to test things aren't easily testable otherwise, such as replication. They're +defined as YAML and run with a custom test runner, but they're just golang unit +tests you can run in your IDE. + +These are difficult to debug because they start multiple separate processes, but +there's support for attaching a debugger to make it possible. + +# Debugging a test + +First set `DOLT_SQL_SERVER_TEST_DEBUG` in your environment. This will increase +the timeouts for queries and other processes to give you time to debug. (Don't +set this when not debugging, as it will lead to failing tests that hang instead +of promptly failing). + +Next, find the test you want to debug and reference it in `TestSingle`, like so: + +```go +func TestSingle(t *testing.T) { +// t.Skip() + RunSingleTest(t, "tests/sql-server-cluster.yaml", "primary comes up and replicates to standby") +} +``` + +Then edit the test to add a `debug_port` for any servers you want to connect to. + +```yaml +- name: primary comes up and replicates to standby + multi_repos: + - name: server1 + ... + server: + args: ["--port", "3309"] + port: 3309 + debug_port: 4009 +``` + +When the test is run, the `sql-server` process will wait for the remote debugger +to connect before starting. You probably want to enable this on every server in +the test definition. Use a different port for each. + +In your IDE, set up N+1 run configurations: one for each of the N servers in the +test, and 1 to run the test itself. Follow the instructions here to create a new +remote debug configuration for each server, using the ports you defined in the +YAML file. + +https://www.jetbrains.com/help/go/attach-to-running-go-processes-with-debugger.html#step-3-create-the-remote-run-debug-configuration-on-the-client-computer + +The main test should be something like +`github.com/dolthub/dolt/integration-tests/go-sql-server-driver#TestSingle`, and +this is where you want to set the `DOLT_SQL_SERVER_TEST_DEBUG` environment +variable if you don't have it set in your main environment. + +Then Run or Debug the main test (either works fine), and wait for the console +output that indicates the server is waiting for the debugger to attach: + +``` +API server listening at: [::]:4009 +``` + +Then Debug the remote-debug configuration(s) you have set up. They should +connect to one of the running server processes, at which point they will +continue execution. Breakpoints and other debugger features should work as +normal. + +# Caveats and gotchas + +* The `dolt` binary run by these tests is whatever is found on your `$PATH`. If + you make changes locally, you need to rebuild that binary to see them + reflected. +* For debugging support, `dlv` needs to be on your `$PATH` as well. +* Some tests restart the server. When this happens, they will once again wait + for a debugger to connect. You'll need to re-invoke the appropriate + remote-debugger connection for the process to continue. +* These tests are expected to work on Windows as well. Just have `dolt.exe` and + `dlv.exe` on your windows `%PATH%` and it should all work. From aae341b31c7f70add4b57bcee1b83ce0cb14578e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 13:58:29 -0700 Subject: [PATCH 070/167] Fixing unix import --- .../doltcore/dtestutils/sql_server_driver/cmd_unix.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go index d8f43f9e9d..ddb3bc3423 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_unix.go @@ -17,7 +17,10 @@ package sql_server_driver -import "syscall" +import ( + "os/exec" + "syscall" +) func ApplyCmdAttributes(cmd *exec.Cmd) { // nothing to do on unix / darwin From 6cb50eb104b73bbe415fd454664e4eddce0ec7eb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 14:33:51 -0700 Subject: [PATCH 071/167] Cleanup from self-review --- go/libraries/doltcore/sqle/database_provider.go | 17 ++--------------- .../doltcore/sqle/dfunctions/active_branch.go | 3 --- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index a72acae7f2..e42e378cbe 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -289,20 +289,7 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database } } p.mu.RUnlock() - - // If the current database is not one of the primary databases, it must be a transitory revision database - // if !foundDatabase && currDb != "" { - // revDb, ok, err := p.databaseForRevision(ctx, currDb) - // if err != nil { - // // We can't return an error from this interface function, so just log a message - // ctx.GetLogger().Warnf("unable to load %q as a database revision: %s", ctx.GetCurrentDatabase(), err.Error()) - // } else if !ok { - // ctx.GetLogger().Warnf("unable to load %q as a database revision", ctx.GetCurrentDatabase()) - // } else { - // all = append(all, revDb) - // } - // } - + // Because we store databases in a map, sort to get a consistent ordering sort.Slice(all, func(i, j int) bool { return strings.ToLower(all[i].Name()) < strings.ToLower(all[j].Name()) @@ -339,7 +326,7 @@ func (p DoltDatabaseProvider) allRevisionDbs(ctx *sql.Context, db dsess.SqlDatab revDbs := make([]sql.Database, len(branches)) for i, branch := range branches { - revDb, ok, err := p.databaseForRevision(ctx, fmt.Sprintf("%s/%s", db.Name(), branch.GetPath()), "") + revDb, ok, err := p.databaseForRevision(ctx, fmt.Sprintf("%s/%s", db.Name(), branch.GetPath()), db.Name()) if err != nil { return nil, err } diff --git a/go/libraries/doltcore/sqle/dfunctions/active_branch.go b/go/libraries/doltcore/sqle/dfunctions/active_branch.go index a6550459e1..771c9bd84c 100644 --- a/go/libraries/doltcore/sqle/dfunctions/active_branch.go +++ b/go/libraries/doltcore/sqle/dfunctions/active_branch.go @@ -54,9 +54,6 @@ func (ab *ActiveBranchFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, er if err != nil { return nil, err } - if currentBranchRef == nil { - return nil, nil - } branches, err := ddb.GetBranches(ctx) if err != nil { From 67dff9edd9a3bb0e7c3b48a8cd82254b29bae1a9 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 14:59:56 -0700 Subject: [PATCH 072/167] More cleanup --- .../doltcore/sqle/dprocedures/dolt_branch.go | 21 ++++------ .../sqle/dprocedures/dolt_checkout.go | 42 ++++--------------- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go index 5002f8d872..eecebac12e 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go @@ -221,11 +221,7 @@ func shouldAllowDefaultBranchDeletion(ctx *sql.Context) bool { // validateBranchNotActiveInAnySessions returns an error if the specified branch is currently // selected as the active branch for any active server sessions. func validateBranchNotActiveInAnySession(ctx *sql.Context, branchName string) error { - currentDbName, _, err := getRevisionForRevisionDatabase(ctx, ctx.GetCurrentDatabase()) - if err != nil { - return err - } - + currentDbName := ctx.GetCurrentDatabase() if currentDbName == "" { return nil } @@ -247,19 +243,16 @@ func validateBranchNotActiveInAnySession(ctx *sql.Context, branchName string) er return false, fmt.Errorf("unexpected session type: %T", session) } - sessionDatabase := dsess.Session.GetCurrentDatabase() - sessionDbName, _, err := getRevisionForRevisionDatabase(ctx, dsess.GetCurrentDatabase()) - if err != nil { - return false, err - } - - if len(sessionDatabase) == 0 || sessionDbName != currentDbName { + sessionDbName := dsess.Session.GetCurrentDatabase() + if len(sessionDbName) == 0 || sessionDbName != currentDbName { return false, nil } - activeBranchRef, err := dsess.CWBHeadRef(ctx, sessionDatabase) + activeBranchRef, err := dsess.CWBHeadRef(ctx, sessionDbName) if err != nil { - return false, err + // The above will throw an error if the current DB doesn't have a head ref, in which case we don't need to + // consider it + return false, nil } if ref.Equals(branchRef, activeBranchRef) { diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index 7925533b6e..a910188022 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -47,13 +47,7 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { if len(currentDbName) == 0 { return 1, fmt.Errorf("Empty database name.") } - - // non-revision database branchName is used to check out a branch on it. - dbName, _, err := getRevisionForRevisionDatabase(ctx, currentDbName) - if err != nil { - return -1, err - } - + apr, err := cli.CreateCheckoutArgParser().Parse(args) if err != nil { return 1, err @@ -65,7 +59,6 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { } dSess := dsess.DSessFromSess(ctx.Session) - // dbData should use the current database data, which can be at revision database. dbData, ok := dSess.GetDbData(ctx, currentDbName) if !ok { return 1, fmt.Errorf("Could not load database %s", currentDbName) @@ -75,7 +68,7 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { // Checking out new branch. if branchOrTrack { - err = checkoutNewBranch(ctx, dbName, dbData, apr, &rsc) + err = checkoutNewBranch(ctx, currentDbName, dbData, apr, &rsc) if err != nil { return 1, err } else { @@ -92,7 +85,7 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { if isBranch, err := actions.IsBranch(ctx, dbData.Ddb, branchName); err != nil { return 1, err } else if isBranch { - err = checkoutBranch(ctx, dbName, branchName) + err = checkoutBranch(ctx, currentDbName, branchName) if errors.Is(err, doltdb.ErrWorkingSetNotFound) { // If there is a branch but there is no working set, // somehow the local branch ref was created without a @@ -108,7 +101,7 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { return 1, err } - err = checkoutBranch(ctx, dbName, branchName) + err = checkoutBranch(ctx, currentDbName, branchName) } if err != nil { return 1, err @@ -116,14 +109,14 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { return 0, nil } - roots, ok := dSess.GetRoots(ctx, dbName) + roots, ok := dSess.GetRoots(ctx, currentDbName) if !ok { - return 1, fmt.Errorf("Could not load database %s", dbName) + return 1, fmt.Errorf("Could not load database %s", currentDbName) } - err = checkoutTables(ctx, roots, dbName, args) + err = checkoutTables(ctx, roots, currentDbName, args) if err != nil && apr.NArg() == 1 { - err = checkoutRemoteBranch(ctx, dbName, dbData, branchName, apr, &rsc) + err = checkoutRemoteBranch(ctx, currentDbName, dbData, branchName, apr, &rsc) } if err != nil { @@ -175,25 +168,6 @@ func createWorkingSetForLocalBranch(ctx *sql.Context, ddb *doltdb.DoltDB, branch return ddb.UpdateWorkingSet(ctx, wsRef, ws, hash.Hash{} /* current hash... */, doltdb.TodoWorkingSetMeta(), nil) } -// getRevisionForRevisionDatabase returns the root database name and revision for a database, or just the root database name if the specified db name is not a revision database. -// TODO: this is no longer necessary, kill it -func getRevisionForRevisionDatabase(ctx *sql.Context, dbName string) (string, string, error) { - doltsess, ok := ctx.Session.(*dsess.DoltSession) - if !ok { - return "", "", fmt.Errorf("unexpected session type: %T", ctx.Session) - } - - db, ok, err := doltsess.Provider().SessionDatabase(ctx, dbName) - if err != nil { - return "", "", err - } - if !ok { - return "", "", sql.ErrDatabaseNotFound.New(dbName) - } - - return db.Name(), db.Revision(), nil -} - // checkoutRemoteBranch checks out a remote branch creating a new local branch with the same name as the remote branch // and set its upstream. The upstream persists out of sql session. func checkoutRemoteBranch(ctx *sql.Context, dbName string, dbData env.DbData, branchName string, apr *argparser.ArgParseResults, rsc *doltdb.ReplicationStatusController) error { From 5b3f4558ae125d8d8de707d5384e65778f089ba2 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 15:06:22 -0700 Subject: [PATCH 073/167] Remove unnecessary TODOs --- go/libraries/doltcore/sqle/dsess/database_session_state.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 80c5f900c6..fb522b3a6a 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -112,7 +112,6 @@ type branchState struct { // case headCommit must be set workingSet *doltdb.WorkingSet // dbData is an accessor for the underlying doltDb - // TODO: move this to DatabaseSessionState only dbData env.DbData // writeSession is this head's write session writeSession writer.WriteSession @@ -121,7 +120,6 @@ type branchState struct { // sessionCache is a collection of cached values used to speed up performance sessionCache *SessionCache // dirty is true if this branch state has uncommitted changes - // TODO NEXT: fill this in and check it dirty bool } From e32524458f351db9ea05f21b66ad0a923de8f349 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 15:58:37 -0700 Subject: [PATCH 074/167] Improved docs --- go/libraries/doltcore/sqle/dsess/doc.go | 71 +++++++++++++++++++++ go/libraries/doltcore/sqle/dsess/session.go | 42 ++---------- 2 files changed, 77 insertions(+), 36 deletions(-) create mode 100755 go/libraries/doltcore/sqle/dsess/doc.go diff --git a/go/libraries/doltcore/sqle/dsess/doc.go b/go/libraries/doltcore/sqle/dsess/doc.go new file mode 100755 index 0000000000..9a125e8f5d --- /dev/null +++ b/go/libraries/doltcore/sqle/dsess/doc.go @@ -0,0 +1,71 @@ +// Copyright 2022 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dsess + +/* + +The dsess package is responsible for storing the state of every database in each session. + +The major players in this process are: + +* sqle.Database: The database implementation we provide to integrate with go-mysql-server's interface is mostly a + wrapper to provide access to the actual storage of tables and rows that are held by dsess.Session. +* sqle.DatabaseProvider: Responsible for creating a new sqle.Database for each database name asked for by the engine, + as well as for managing the details of replication on the databases it returns. +* dsess.Session: Responsible for maintaining the state of each session, including the data access for any row data. + Each physical dolt database in the provider can have the state of multiple branch heads managed by a session. This + state is loaded on demand from the provider as the client asks for different databases by name, as `dolt_checkout` + is called, etc. +* dsess.DoltTransaction: Records a start state (noms root) for each database managed by the transaction. Responsible + for committing new data as the result of a COMMIT or dolt_commit() by merging this start state with session changes + as appropriate. + +The rough flow of data between the engine and this package: + +1) START TRANSACTION calls dsess.Session.StartTransaction() to create a new dsess.DoltTransaction. This transaction + takes a snapshot of the current noms root for each database known to the provider and records these as part of the + transaction. This method clears out all cached state. +2) The engine calls DatabaseProvider.Database() to get a sqle.Database for each database name included in a query, + including statements like `USE db`. +3) Databases have access to tables, views, and other schema elements that they provide to the engine upon request as + part of query analysis, row iteration, etc. As a rule, this data is loaded from the session when asked for. Databases, + tables, views, and other structures in the sqle package are best understood as pass-through entities that always + defer to the session for their actual data. +4) When actual data is required, a table or other schema element asks the session for the data. The primary interface + for this exchange is Session.LookupDbState(), which takes a database name. +5) Eventually, the client session issues a COMMIT or DOLT_COMMIT() statement. This calls Session.CommitTransaction(), + which enforces business logic rules around the commit and then calls DoltTransaction.Commit() to persist the changes. + +Databases managed by the provider and the session can be referred to by either a base name (myDb) or a fully qualified +name (myDb/myBranch). The details of this are a little bit subtle: + +* Database names that aren't qualified with a revision specifier resolve to either a) the default branch head, or + b) whatever branch head was last checked out with dolt_checkout(). Changing the branch head referred to by an + unqualified database name is the primary purpose of dolt_checkout(). +* `mydb/branch` always resolves to that branch head, as it existed at transaction start +* Database names exposed to the engine are always `mydb`, never `mydb/branch`. This includes the result of + `select database()`. This is because the engine expects base database names when e.g. checking GRANTs, returning + information the information schema table, etc. +* sqle.Database has an external name it exposes to the engine via Name(), as well as an internal name that includes a + revision qualifier, RevisionQualifiedName(). The latter should always be used internally when accessing session data, + including rows and all other table data. It's only appropriate to use an unqualified database name when you want + the current checked out HEAD. + +It's possible to alter the data on multiple HEADS in a single session, but we currently restrict the users to +committing a single one. It doesn't need to be the checked out head -- we simply look for a single dirty branch head +state and commit that one. If there is more than one, it's an error. We may allow multiple branch heads to be updated +in a single transaction in the future. + + */ diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 4bd6075232..3b16ab43bf 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -212,16 +212,12 @@ func SplitRevisionDbName(dbName string) (string, string) { return baseName, rev } -// TODO NEXT: the lookupdbstate method is the key abstraction point. It proxies all non-revisoined DBs to a revisioned -// state, based on the current db (the default branch if none). The session stores all data by working set ref. DB -// names are masked on return in the case of a non-revisined DB. Session stae is also responsible for keeping track of -// the checked out branch in the case of a default (no branch-specified) db connection. -// Alternate idea: branch head is always set correctly in response to a USE statement, OR a checkout procedure. The -// latter implicitly updates the current database. You also get a revision db checked out on connection to no branch. -// The original idea is more tractable for now -- too many things break with the latter approach, although it's cleaner -// in many respects. Biggest blocker is grants, which are currently tied to the base database name and probably need to -// stay that way. Unless I can come up with some clever workaround... -// Possible workaround for permissions: new GMS interface for "permissionDbName" or similar, workable? +// LookupDbState returns the session state for the database named. Unqualified database names, e.g. `mydb` get resolved +// to the currently checked out HEAD, which could be a branch, a commit, a tag, etc. Revision-qualified database names, +// e.g. `mydb/branch1` get resolved to the session state for the revision named. +// A note on unqualified database names: unqualified names will resolve to a) the head last checked out with +// `dolt_checkout`, or b) the database's default branch, if this session hasn't called `dolt_checkout` yet. +// Also returns a bool indicating whether the database was found, and an error if one occurred. func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (SessionState, bool, error) { s, ok, err := d.lookupDbState(ctx, dbName) if err != nil { @@ -231,32 +227,6 @@ func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (SessionSta return s, ok, nil } -// func (d *DoltSession) CurrentDbState(ctx *sql.Context) (SessionState, bool, error) { -// db := ctx.GetCurrentDatabase() -// if db == "" { -// return nil, false, fmt.Errorf("no current database") -// } -// -// // TODO: this should always be false, right? -// isRevisionDb := strings.Contains(db, DbRevisionDelimiter) -// if !isRevisionDb { -// d.mu.Lock() -// dbState, ok := d.dbStates[strings.ToLower(db)] -// d.mu.Unlock() -// -// if !ok { -// return d.lookupDbState(ctx, db) -// } -// } -// -// s, ok, err := d.lookupDbState(ctx, db) -// if err != nil { -// return nil, false, err -// } -// -// return s, ok, nil -// } - // RemoveDbState invalidates any cached db state in this session, for example, if a database is dropped. func (d *DoltSession) RemoveDbState(_ *sql.Context, dbName string) error { d.mu.Lock() From 533e069c919499aece574bb5b9996d606274535b Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:02:02 -0700 Subject: [PATCH 075/167] Renamed clear state method --- go/libraries/doltcore/sqle/dsess/session.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 3b16ab43bf..eeb90d0770 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -274,8 +274,7 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { // StartTransaction refreshes the state of this session and starts a new transaction. func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.TransactionCharacteristic) (sql.Transaction, error) { // New transaction, clear all session state - // TODO: revisit this - d.clearRevisionDbState() + d.clear() // Take a snapshot of the current noms root for every database under management doltDatabases := d.provider.DoltDatabases() @@ -312,9 +311,8 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra return NewMultiHeadTransaction(ctx, txDbs, tCharacteristic) } -// clearRevisionDbState clears all revision DB states for this session. This is necessary on transaction start, -// because they will be re-initialized with the current branch head / working set. -func (d *DoltSession) clearRevisionDbState() { +// clear clears all DB state for this session +func (d *DoltSession) clear() { d.mu.Lock() defer d.mu.Unlock() @@ -601,7 +599,7 @@ func (d *DoltSession) newPendingCommit(ctx *sql.Context, branchState *branchStat // Rollback rolls the given transaction back func (d *DoltSession) Rollback(ctx *sql.Context, tx sql.Transaction) error { // Nothing to do here, we just throw away all our work and let a new transaction begin next statement - d.clearRevisionDbState() + d.clear() return nil } From 0bf7bd2c868d32389c7ac689832be6f61328226a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:08:28 -0700 Subject: [PATCH 076/167] Better naming and cleanup --- go/libraries/doltcore/sqle/dsess/session.go | 29 +++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index eeb90d0770..d28530177a 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -281,8 +281,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra txDbs := make([]SqlDatabase, 0, len(doltDatabases)) for _, db := range doltDatabases { // TODO: this nil check is only necessary to support UserSpaceDatabase and clusterDatabase, come up with a better set of - // interfaces - // to capture these capabilities + // interfaces to capture these capabilities ddb := db.DbData().Ddb if ddb != nil { rrd, ok := db.(RemoteReadReplicaDatabase) @@ -436,7 +435,7 @@ func (d *DoltSession) CommitWorkingSet(ctx *sql.Context, dbName string, tx sql.T return ws, nil, err } - _, err := d.doCommit(ctx, dbName, tx, commitFunc) + _, err := d.commitCurrentHead(ctx, dbName, tx, commitFunc) return err } @@ -446,7 +445,7 @@ func (d *DoltSession) commitWorkingSet(ctx *sql.Context, branchState *branchStat return ws, nil, err } - _, err := d.doCommitInternal(ctx, branchState, tx, commitFunc) + _, err := d.commitBranchState(ctx, branchState, tx, commitFunc) return err } @@ -476,15 +475,20 @@ func (d *DoltSession) DoltCommit( return ws, commit, err } - return d.doCommit(ctx, dbName, tx, commitFunc) + return d.commitCurrentHead(ctx, dbName, tx, commitFunc) } // doCommitFunc is a function to write to the database, which involves updating the working set and potentially // updating HEAD with a new commit type doCommitFunc func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, *doltdb.Commit, error) -// doCommit exercise the business logic for a particular doCommitFunc -func (d *DoltSession) doCommitInternal(ctx *sql.Context, branchState *branchState, tx sql.Transaction, commitFunc doCommitFunc) (*doltdb.Commit, error) { +// commitBranchState performs a commit for the branch state given, using the doCommitFunc provided +func (d *DoltSession) commitBranchState( + ctx *sql.Context, + branchState *branchState, + tx sql.Transaction, + commitFunc doCommitFunc, +) (*doltdb.Commit, error) { dtx, ok := tx.(*DoltTransaction) if !ok { return nil, fmt.Errorf("expected a DoltTransaction") @@ -499,19 +503,16 @@ func (d *DoltSession) doCommitInternal(ctx *sql.Context, branchState *branchStat return newCommit, nil } -// doCommit exercise the business logic for a particular doCommitFunc -func (d *DoltSession) doCommit(ctx *sql.Context, dbName string, tx sql.Transaction, commitFunc doCommitFunc) (*doltdb.Commit, error) { +// commitCurrentHead commits the current HEAD for the database given, using the doCommitFunc provided +func (d *DoltSession) commitCurrentHead(ctx *sql.Context, dbName string, tx sql.Transaction, commitFunc doCommitFunc) (*doltdb.Commit, error) { branchState, ok, err := d.lookupDbState(ctx, dbName) if err != nil { return nil, err } else if !ok { - // It's possible that we don't have dbstate if the user has created an in-Memory database. Moreover, - // the analyzer will check for us whether a db exists or not. - // TODO: fix this - return nil, nil + return nil, sql.ErrDatabaseNotFound.New(dbName) } - return d.doCommitInternal(ctx, branchState, tx, commitFunc) + return d.commitBranchState(ctx, branchState, tx, commitFunc) } // PendingCommitAllStaged returns a pending commit with all tables staged. Returns nil if there are no changes to stage. From 35e3cc84d84a571002233bc0410e9606a3cbaa7a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:17:41 -0700 Subject: [PATCH 077/167] Cleanup in working set management --- go/libraries/doltcore/sqle/dsess/session.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index d28530177a..77990982b5 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -777,11 +777,10 @@ func (d *DoltSession) ResolveRootForRef(ctx *sql.Context, dbName, refStr string) // SetRoot sets a new root value for the session for the database named. This is the primary mechanism by which data // changes are communicated to the engine and persisted back to disk. All data changes should be followed by a call to // update the session's root value via this method. +// The dbName given should generally be a revision-qualified database name. // Data changes contained in the |newRoot| aren't persisted until this session is committed. // TODO: rename to SetWorkingRoot -// TODO: kill this method func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.RootValue) error { - // TODO: this is redundant with work done in setRoot branchState, _, err := d.lookupDbState(ctx, dbName) if err != nil { return err @@ -796,8 +795,7 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R } if branchState.readOnly { - // TODO: Return an error here? - return nil + return fmt.Errorf("cannot set root on read-only session") } branchState.workingSet = branchState.WorkingSet().WithWorkingRoot(newRoot) @@ -808,8 +806,11 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R // via setRoot. This method is for clients that need to update more of the session state, such as the dolt_ functions. // Unlike setting the working root, this method always marks the database state dirty. func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roots) error { - // TODO: handle HEAD here? - // TODO: need to make sure we use a revision qualified DB name here + _, rev := SplitRevisionDbName(dbName) + if rev != "" { + return fmt.Errorf("cannot set roots for a revision database") + } + sessionState, _, err := d.LookupDbState(ctx, dbName) if err != nil { return err @@ -825,8 +826,6 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo // SetWorkingSet sets the working set for this session. // Unlike setting the working root alone, this method always marks the session dirty. -// TODO: this is doing a lot of resolve work that should only happen once, at initialization time -// TODO: find uses of this for dirty changes func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb.WorkingSet) error { if ws == nil { panic("attempted to set a nil working set for the session") @@ -853,7 +852,6 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. } branchState.dirty = true - return nil } From e97a19681fb9a414edd1ba8c6dbe7e6fd9f2f9f8 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:28:59 -0700 Subject: [PATCH 078/167] Renamed constructor --- go/libraries/doltcore/sqle/database.go | 1 - go/libraries/doltcore/sqle/dsess/session.go | 6 +++--- go/libraries/doltcore/sqle/dsess/session_db_provider.go | 1 - go/libraries/doltcore/sqle/dsess/transactions.go | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index dd013a3d7d..69425419a4 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -132,7 +132,6 @@ func initialDBState(ctx *sql.Context, db dsess.SqlDatabase, branch string) (dses return initialStateForRevisionDb(ctx, db) } - // TODO: this should never be true return initialDbState(ctx, db, branch) } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 77990982b5..c40f1f19fb 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -307,7 +307,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - return NewMultiHeadTransaction(ctx, txDbs, tCharacteristic) + return NewDoltTransaction(ctx, txDbs, tCharacteristic) } // clear clears all DB state for this session @@ -855,7 +855,8 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return nil } -// SetCurrentHead sets the currently connected head revision spec for this session. +// SetCurrentHead sets the currently connected head revision spec for this session. This changes the revision that +// unqualified references to the database name resolve to, and is only done by dolt_checkout(). func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref.WorkingSetRef) error { headRef, err := wsRef.ToHeadRef() if err != nil { @@ -1149,7 +1150,6 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } // This has to happen after SetWorkingSet above, since it does a stale check before its work - // TODO: this needs to be kept up to date as the working set ref changes branchState.headCommit = dbState.HeadCommit if sessionState.Err == nil { diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index f575598666..70b7a764f0 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -55,7 +55,6 @@ type RevisionDatabase interface { // string naming that branch or tag. For other revision specs, e.g. "HEAD~2", the revision is a commit hash. type RevisionType int -// TODO: do we need a working set type here, or no? const ( RevisionTypeNone RevisionType = iota RevisionTypeBranch diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index f2d543ae2a..d53b3f0f6e 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -90,7 +90,7 @@ type savepoint struct { root *doltdb.RootValue } -func NewMultiHeadTransaction( +func NewDoltTransaction( ctx *sql.Context, dbs []SqlDatabase, tCharacteristic sql.TransactionCharacteristic, From 05e3f666d2757fab144b541d97b447dfdd048049 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:33:06 -0700 Subject: [PATCH 079/167] Added prepared test --- .../doltcore/sqle/enginetest/dolt_engine_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index f37c28e9e0..eb8517974e 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -49,7 +49,7 @@ var skipPrepared bool // SkipPreparedsCount is used by the "ci-check-repo CI workflow // as a reminder to consider prepareds when adding a new // enginetest suite. -const SkipPreparedsCount = 86 +const SkipPreparedsCount = 85 const skipPreparedFlag = "DOLT_SKIP_PREPARED_ENGINETESTS" @@ -1515,6 +1515,16 @@ func TestDoltCheckout(t *testing.T) { } } +func TestDoltCheckoutPrepared(t *testing.T) { + for _, script := range DoltCheckoutScripts { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScriptPrepared(t, h, script) + }() + } +} + func TestDoltBranch(t *testing.T) { for _, script := range DoltBranchScripts { func() { From 19e83654a1f949f54faa180d35f45ace90870fcf Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:37:42 -0700 Subject: [PATCH 080/167] Cleaned up a couple places that needed a qualified db name --- go/libraries/doltcore/sqle/database.go | 4 ++-- go/libraries/doltcore/sqle/tables.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 69425419a4..b4c3667dc8 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -982,13 +982,13 @@ func (db Database) CreateTemporaryTable(ctx *sql.Context, tableName string, pkSc return ErrInvalidTableName.New(tableName) } - tmp, err := NewTempTable(ctx, db.ddb, pkSch, tableName, db.name, db.editOpts, collation) + tmp, err := NewTempTable(ctx, db.ddb, pkSch, tableName, db.RevisionQualifiedName(), db.editOpts, collation) if err != nil { return err } ds := dsess.DSessFromSess(ctx.Session) - ds.AddTemporaryTable(ctx, db.Name(), tmp) + ds.AddTemporaryTable(ctx, db.RevisionQualifiedName(), tmp) return nil } diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 1aba814649..5a85b4ecad 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -1390,7 +1390,7 @@ func (t *AlterableDoltTable) RewriteInserter( } writeSession := writer.NewWriteSession(dt.Format(), newWs, ait, opts) - ed, err := writeSession.GetTableWriter(ctx, t.Name(), t.db.Name(), sess.SetRoot, false) + ed, err := writeSession.GetTableWriter(ctx, t.Name(), t.db.RevisionQualifiedName(), sess.SetRoot, false) if err != nil { return nil, err } From aee5aeb48f794a57585fd03bb491201f62e41ad6 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:39:33 -0700 Subject: [PATCH 081/167] One more --- go/libraries/doltcore/sqle/database.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index b4c3667dc8..05fc751373 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -190,7 +190,7 @@ func (db Database) GetTableInsensitive(ctx *sql.Context, tblName string) (sql.Ta // We start by first checking whether the input table is a temporary table. Temporary tables with name `x` take // priority over persisted tables of name `x`. ds := dsess.DSessFromSess(ctx.Session) - if tbl, ok := ds.GetTemporaryTable(ctx, db.Name(), tblName); ok { + if tbl, ok := ds.GetTemporaryTable(ctx, db.RevisionQualifiedName(), tblName); ok { return tbl, ok, nil } From ccb8de1ae837dd62b09c4b65ce510f992b97c2cb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 22 May 2023 16:43:33 -0700 Subject: [PATCH 082/167] Removed a couple TODOs --- go/libraries/doltcore/sqle/dsess/session.go | 1 - go/libraries/doltcore/sqle/writer/noms_write_session.go | 2 -- 2 files changed, 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index c40f1f19fb..10ca196079 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -845,7 +845,6 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return err } - // TODO: remove this err = branchState.WriteSession().SetWorkingSet(ctx, ws) if err != nil { return err diff --git a/go/libraries/doltcore/sqle/writer/noms_write_session.go b/go/libraries/doltcore/sqle/writer/noms_write_session.go index 30ed68811c..d8afada9b9 100644 --- a/go/libraries/doltcore/sqle/writer/noms_write_session.go +++ b/go/libraries/doltcore/sqle/writer/noms_write_session.go @@ -34,11 +34,9 @@ import ( // It's responsible for creating and managing the lifecycle of TableWriter's. type WriteSession interface { // GetTableWriter creates a TableWriter and adds it to the WriteSession. - // TODO: track down refs to this, make sure they use the revision-qualified name GetTableWriter(ctx context.Context, table, db string, setter SessionRootSetter, batched bool) (TableWriter, error) // SetWorkingSet modifies the state of the WriteSession. The WorkingSetRef of |ws| must match the existing Ref. - // TODO: kill this, do not reuse write sessions between working sets SetWorkingSet(ctx context.Context, ws *doltdb.WorkingSet) error // GetOptions returns the editor.Options for this session. From 04e3421d543ebbb7607ed07f7fb595b625374b49 Mon Sep 17 00:00:00 2001 From: zachmu Date: Tue, 23 May 2023 18:20:59 +0000 Subject: [PATCH 083/167] [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh --- go/go.sum | 6 -- .../dtestutils/sql_server_driver/cmd.go | 8 +- .../sql_server_driver/cmd_windows.go | 2 +- .../dtestutils/sql_server_driver/server.go | 2 +- go/libraries/doltcore/merge/merge.go | 2 +- .../doltcore/sqle/database_provider.go | 86 +++++++++---------- .../doltcore/sqle/dprocedures/dolt_branch.go | 2 +- .../sqle/dprocedures/dolt_checkout.go | 8 +- .../doltcore/sqle/dprocedures/dolt_merge.go | 6 +- .../sqle/dsess/database_session_state.go | 42 ++++----- go/libraries/doltcore/sqle/dsess/doc.go | 28 +++--- go/libraries/doltcore/sqle/dsess/session.go | 72 ++++++++-------- .../sqle/dsess/session_db_provider.go | 8 +- .../doltcore/sqle/dsess/transactions.go | 64 +++++++------- .../sqle/enginetest/dolt_engine_test.go | 4 +- .../doltcore/sqle/enginetest/dolt_queries.go | 22 ++--- .../sqle/enginetest/dolt_queries_merge.go | 10 +-- .../sqle/enginetest/dolt_server_test.go | 6 +- .../enginetest/dolt_transaction_queries.go | 12 +-- 19 files changed, 192 insertions(+), 198 deletions(-) diff --git a/go/go.sum b/go/go.sum index a6479acaa9..4d68ccb553 100644 --- a/go/go.sum +++ b/go/go.sum @@ -168,10 +168,6 @@ 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-20230516121657-5424676dd4ac h1:/bsG4AyV5MesUPw7LSkxHKMsP9f+LSLrsMbBxLP6+Mk= github.com/dolthub/go-icu-regex v0.0.0-20230516121657-5424676dd4ac/go.mod h1:xLKpPutKiF9FxxcLG3gf/JA95YZQNAqBegkDRe1AZF4= -github.com/dolthub/go-mysql-server v0.15.1-0.20230517042856-2405a8d89854 h1:2AMV4KSxCp6sHA3eWlKX/93HEVNacfqFJhSQw39VRh4= -github.com/dolthub/go-mysql-server v0.15.1-0.20230517042856-2405a8d89854/go.mod h1:J+NMF5CgU6b3tBI4G2QVb1AUSf+YoPDDCsZkcM7rY1I= -github.com/dolthub/go-mysql-server v0.15.1-0.20230517201855-8477b3b02370 h1:YGNpsPKq7u5cAow/5Sjb3ncu5Qh6SwCp5jBBMhtCnRs= -github.com/dolthub/go-mysql-server v0.15.1-0.20230517201855-8477b3b02370/go.mod h1:J+NMF5CgU6b3tBI4G2QVb1AUSf+YoPDDCsZkcM7rY1I= github.com/dolthub/go-mysql-server v0.15.1-0.20230519012556-81c365aafb54 h1:ZvK3NmxZbHr/DFxec3aF8KY+tahV72D1fZHm2p3cMxQ= github.com/dolthub/go-mysql-server v0.15.1-0.20230519012556-81c365aafb54/go.mod h1:y9ZGm0yf/UFfztugI31qSLAcvG/BfmkVoffu+uv/0MY= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= @@ -184,8 +180,6 @@ 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-20230508201056-fc3ee4c11ca5 h1:Odi5ZtzgfS3B6MEwe5c5ADV70pjdnI3jbWr9XI5/vfg= -github.com/dolthub/vitess v0.0.0-20230508201056-fc3ee4c11ca5/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= github.com/dolthub/vitess v0.0.0-20230518120917-a3e13f1a546a h1:KnNvaz8GaUvMm+jvm11nGVlpR2lGaKQfWU4yaXLA4yg= github.com/dolthub/vitess v0.0.0-20230518120917-a3e13f1a546a/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go index bf39d66f49..4245cac830 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd.go @@ -46,7 +46,7 @@ func init() { } path = filepath.Clean(path) var err error - + DoltPath, err = exec.LookPath(path) if err != nil { log.Printf("did not find dolt binary: %v\n", err.Error()) @@ -104,7 +104,7 @@ func (u DoltUser) DoltCmd(args ...string) *exec.Cmd { func (u DoltUser) DoltDebug(debuggerPort int, args ...string) *exec.Cmd { if DelvePath != "" { - dlvArgs := []string { + dlvArgs := []string{ fmt.Sprintf("--listen=:%d", debuggerPort), "--headless", "--api-version=2", @@ -253,7 +253,7 @@ func DebugSqlServer(dc DoltCmdable, debuggerPort int, opts ...SqlServerOpt) (*Sq if !ok { return nil, fmt.Errorf("%T does not implement DoltDebuggable", dc) } - + cmd := ddb.DoltDebug(debuggerPort, "sql-server") return runSqlServerCommand(dc, append(opts, WithDebugPort(debuggerPort)), cmd) } @@ -276,7 +276,7 @@ func runSqlServerCommand(dc DoltCmdable, opts []SqlServerOpt, cmd *exec.Cmd) (*S wg.Wait() close(done) }() - + server := &SqlServer{ Done: done, Cmd: cmd, diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go index 451a0970ec..649c895d32 100755 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/cmd_windows.go @@ -34,7 +34,7 @@ func (s *SqlServer) GracefulStop() error { if err != nil { return err } - + <-s.Done _, err = s.Cmd.Process.Wait() diff --git a/go/libraries/doltcore/dtestutils/sql_server_driver/server.go b/go/libraries/doltcore/dtestutils/sql_server_driver/server.go index 8f64f69973..00178c2937 100644 --- a/go/libraries/doltcore/dtestutils/sql_server_driver/server.go +++ b/go/libraries/doltcore/dtestutils/sql_server_driver/server.go @@ -163,7 +163,7 @@ type Server struct { Port int `yaml:"port"` // DebugPort if set to a non-zero value will cause this server to be started with |dlv| listening for a debugger - // connection on the port given. + // connection on the port given. DebugPort int `yaml:"debug_port"` // Assertions to be run against the log output of the server process diff --git a/go/libraries/doltcore/merge/merge.go b/go/libraries/doltcore/merge/merge.go index 7cd4eb74ad..2082072d3e 100644 --- a/go/libraries/doltcore/merge/merge.go +++ b/go/libraries/doltcore/merge/merge.go @@ -157,7 +157,7 @@ func MergeRoots( tblToStats := make(map[string]*MergeStats) mergedRoot := ourRoot - + // Merge tables one at a time. This is done based on name. With table names from ourRoot being merged first, // renaming a table will return delete/modify conflict error consistently. // TODO: merge based on a more durable table identity that persists across renames diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index e42e378cbe..9146d0051d 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -289,7 +289,7 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database } } p.mu.RUnlock() - + // Because we store databases in a map, sort to get a consistent ordering sort.Slice(all, func(i, j int) bool { return strings.ToLower(all[i].Name()) < strings.ToLower(all[j].Name()) @@ -787,7 +787,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual } return db, true, nil case dsess.RevisionTypeNone: - // Returning an error with the fully qualified db name here is our only opportunity to do so in some cases (such + // Returning an error with the fully qualified db name here is our only opportunity to do so in some cases (such // as when a branch is deleted by another client) return nil, false, sql.ErrDatabaseNotFound.New(revisionQualifiedName) default: @@ -1026,20 +1026,20 @@ func resolveAncestorSpec(ctx *sql.Context, revSpec string, ddb *doltdb.DoltDB) ( func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (dsess.SqlDatabase, bool, error) { baseName := name isRevisionDbName := strings.Contains(name, dsess.DbRevisionDelimiter) - + if isRevisionDbName { // TODO: formalize and enforce this rule (can't allow DBs with / in the name) // TODO: some connectors will take issue with the /, we need other mechanisms to support them parts := strings.SplitN(name, dsess.DbRevisionDelimiter, 2) baseName = parts[0] } - + var ok bool p.mu.RLock() db, ok := p.databases[strings.ToLower(baseName)] standby := *p.isStandby p.mu.RUnlock() - + // If the database doesn't exist and this is a read replica, attempt to clone it from the remote if !ok { var err error @@ -1053,20 +1053,20 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds return nil, false, nil } } - + // Some DB implementations don't support addressing by versioned names, so return directly if we have one of those if !db.Versioned() { return wrapForStandby(db, standby), true, nil } - // Convert to a revision database before returning. If we got a non-qualified name, convert it to a qualified name - // using the session's current head + // Convert to a revision database before returning. If we got a non-qualified name, convert it to a qualified name + // using the session's current head revisionQualifiedName := name if !isRevisionDbName { sess := dsess.DSessFromSess(ctx.Session) - // A newly created session may not have any info on current head stored yet, in which case we get the default - // branch for the db itself instead. + // A newly created session may not have any info on current head stored yet, in which case we get the default + // branch for the db itself instead. head, ok, err := sess.CurrentHead(ctx, baseName) if err != nil { return nil, false, err @@ -1083,7 +1083,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds revisionQualifiedName = baseName + dsess.DbRevisionDelimiter + head } - + db, ok, err := p.databaseForRevision(ctx, revisionQualifiedName, name) if err != nil { return nil, false, err @@ -1091,7 +1091,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds if !ok { return nil, false, nil } - + return wrapForStandby(db, standby), true, nil } @@ -1254,41 +1254,41 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s switch v := srcDb.(type) { case ReadOnlyDatabase: db := Database{ - name: srcDb.Name(), + name: srcDb.Name(), requestedName: requestedName, - ddb: v.ddb, - rsw: static, - rsr: static, - gs: v.gs, - editOpts: v.editOpts, - revision: revSpec, - revType: dsess.RevisionTypeBranch, + ddb: v.ddb, + rsw: static, + rsr: static, + gs: v.gs, + editOpts: v.editOpts, + revision: revSpec, + revType: dsess.RevisionTypeBranch, } return ReadOnlyDatabase{db}, nil case Database: return Database{ - name: srcDb.Name(), + name: srcDb.Name(), requestedName: requestedName, - ddb: v.ddb, - rsw: static, - rsr: static, - gs: v.gs, - editOpts: v.editOpts, - revision: revSpec, - revType: dsess.RevisionTypeBranch, + ddb: v.ddb, + rsw: static, + rsr: static, + gs: v.gs, + editOpts: v.editOpts, + revision: revSpec, + revType: dsess.RevisionTypeBranch, }, nil case ReadReplicaDatabase: return ReadReplicaDatabase{ Database: Database{ - name: srcDb.Name(), + name: srcDb.Name(), requestedName: requestedName, - ddb: v.ddb, - rsw: static, - rsr: static, - gs: v.gs, - editOpts: v.editOpts, - revision: revSpec, - revType: dsess.RevisionTypeBranch, + ddb: v.ddb, + rsw: static, + rsr: static, + gs: v.gs, + editOpts: v.editOpts, + revision: revSpec, + revType: dsess.RevisionTypeBranch, }, remote: v.remote, srcDB: v.srcDB, @@ -1365,14 +1365,14 @@ func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.I func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { return ReadOnlyDatabase{Database: Database{ - name: srcDb.Name(), + name: srcDb.Name(), requestedName: requestedName, - ddb: srcDb.DbData().Ddb, - rsw: srcDb.DbData().Rsw, - rsr: srcDb.DbData().Rsr, - editOpts: srcDb.editOpts, - revision: revSpec, - revType: dsess.RevisionTypeTag, + ddb: srcDb.DbData().Ddb, + rsw: srcDb.DbData().Rsw, + rsr: srcDb.DbData().Rsr, + editOpts: srcDb.editOpts, + revision: revSpec, + revType: dsess.RevisionTypeTag, }}, nil } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go index eecebac12e..3669788fcc 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go @@ -250,7 +250,7 @@ func validateBranchNotActiveInAnySession(ctx *sql.Context, branchName string) er activeBranchRef, err := dsess.CWBHeadRef(ctx, sessionDbName) if err != nil { - // The above will throw an error if the current DB doesn't have a head ref, in which case we don't need to + // The above will throw an error if the current DB doesn't have a head ref, in which case we don't need to // consider it return false, nil } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index a910188022..0fb5f1f6ce 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -47,7 +47,7 @@ func doDoltCheckout(ctx *sql.Context, args []string) (int, error) { if len(currentDbName) == 0 { return 1, fmt.Errorf("Empty database name.") } - + apr, err := cli.CreateCheckoutArgParser().Parse(args) if err != nil { return 1, err @@ -242,7 +242,7 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * if err != nil { return err } - + if setTrackUpstream { err = env.SetRemoteUpstreamForRefSpec(dbData.Rsw, refSpec, remoteName, ref.NewBranchRef(remoteBranchName)) if err != nil { @@ -258,7 +258,7 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * } } } - + // We need to commit the transaction here or else the branch we just created isn't visible to the current transaction, // and we are about to switch to it. So set the new branch head for the new transaction, then commit this one sess := dsess.DSessFromSess(ctx.Session) @@ -271,7 +271,7 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * if err != nil { return err } - + return sess.SetCurrentHead(ctx, dbName, wsRef) } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go index bca9f242da..de1ec43901 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go @@ -105,7 +105,7 @@ func doDoltMerge(ctx *sql.Context, args []string) (int, int, error) { if err != nil { return noConflictsOrViolations, threeWayMerge, err } - + // Because this commit happens outside the engine's control, we need to manually clear the transaction ctx.SetTransaction(nil) @@ -301,7 +301,7 @@ func executeFFMerge(ctx *sql.Context, dbName string, squash bool, ws *doltdb.Wor if err != nil { return ws, err } - + // because this commit happens outside the SQL engine's awareness, we need to manually clear the transaction ctx.SetTransaction(nil) } @@ -359,7 +359,7 @@ func executeNoFFMerge( if err != nil { return nil, err } - + // because this commit happens outside the SQL engine's awareness, we need to manually clear the transaction ctx.SetTransaction(nil) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index fb522b3a6a..566ab9009f 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -35,12 +35,12 @@ type InitialDbState struct { // RootValue must be set. HeadCommit *doltdb.Commit // HeadRoot is the root value for databases without a HeadCommit. Nil for databases with a HeadCommit. - HeadRoot *doltdb.RootValue - ReadOnly bool - DbData env.DbData - Remotes map[string]env.Remote - Branches map[string]env.BranchConfig - Backups map[string]env.Remote + HeadRoot *doltdb.RootValue + ReadOnly bool + DbData env.DbData + Remotes map[string]env.Remote + Branches map[string]env.BranchConfig + Backups map[string]env.Remote // If err is set, this InitialDbState is partially invalid, but may be // usable to initialize a database at a revision specifier, for @@ -58,25 +58,25 @@ type SessionDatabase interface { // DatabaseSessionState is the set of all information for a given database in this session. type DatabaseSessionState struct { - // dbName is the name of the database this state applies to. This is always the base name of the database, without + // dbName is the name of the database this state applies to. This is always the base name of the database, without // a revision qualifier. - dbName string - // currRevSpec is the current revision spec of the database when referred to by its base name. Changes when a + dbName string + // currRevSpec is the current revision spec of the database when referred to by its base name. Changes when a // `dolt_checkout` or `use` statement is executed. currRevSpec string // currRevType is the current revision type of the database when referred to by its base name. Changes when a // `dolt_checkout` or `use` statement is executed. currRevType RevisionType - // checkedOutRevSpec is the checked out revision specifier of the database. Changes only when a `dolt_checkout` + // checkedOutRevSpec is the checked out revision specifier of the database. Changes only when a `dolt_checkout` // occurs. `USE mydb` without a revision qualifier will get this revision. checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session - heads map[string]*branchState + heads map[string]*branchState // globalState is the global state of this session (shared by all sessions for a particular db) - globalState globalstate.GlobalState + globalState globalstate.GlobalState // tmpFileDir is the directory to use for temporary files for this database - tmpFileDir string - + tmpFileDir string + // Same as InitialDbState.Err, this signifies that this // DatabaseSessionState is invalid. LookupDbState returning a // DatabaseSessionState with Err != nil will return that err. @@ -90,7 +90,7 @@ func NewEmptyDatabaseSessionState() *DatabaseSessionState { } // SessionState is the public interface for dealing with session state outside this package. Session-state is always -// branch-specific. +// branch-specific. type SessionState interface { WorkingSet() *doltdb.WorkingSet WorkingRoot() *doltdb.RootValue @@ -103,20 +103,20 @@ type SessionState interface { type branchState struct { // dbState is the parent database state for this branch head state dbState *DatabaseSessionState - // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which + // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which // case headRoot must be set. - headCommit *doltdb.Commit + headCommit *doltdb.Commit // HeadRoot is the root value for databases without a headCommit. Nil for databases with a headCommit. - headRoot *doltdb.RootValue + headRoot *doltdb.RootValue // workingSet is the working set for this database. May be nil for databases tied to a detached root value, in which // case headCommit must be set workingSet *doltdb.WorkingSet // dbData is an accessor for the underlying doltDb - dbData env.DbData + dbData env.DbData // writeSession is this head's write session writeSession writer.WriteSession // readOnly is true if this database is read only - readOnly bool + readOnly bool // sessionCache is a collection of cached values used to speed up performance sessionCache *SessionCache // dirty is true if this branch state has uncommitted changes @@ -125,7 +125,7 @@ type branchState struct { func NewEmptyBranchState(dbState *DatabaseSessionState) *branchState { return &branchState{ - dbState: dbState, + dbState: dbState, sessionCache: newSessionCache(), } } diff --git a/go/libraries/doltcore/sqle/dsess/doc.go b/go/libraries/doltcore/sqle/dsess/doc.go index 9a125e8f5d..b1c1e6bb19 100755 --- a/go/libraries/doltcore/sqle/dsess/doc.go +++ b/go/libraries/doltcore/sqle/dsess/doc.go @@ -20,32 +20,32 @@ The dsess package is responsible for storing the state of every database in each The major players in this process are: -* sqle.Database: The database implementation we provide to integrate with go-mysql-server's interface is mostly a +* sqle.Database: The database implementation we provide to integrate with go-mysql-server's interface is mostly a wrapper to provide access to the actual storage of tables and rows that are held by dsess.Session. -* sqle.DatabaseProvider: Responsible for creating a new sqle.Database for each database name asked for by the engine, +* sqle.DatabaseProvider: Responsible for creating a new sqle.Database for each database name asked for by the engine, as well as for managing the details of replication on the databases it returns. -* dsess.Session: Responsible for maintaining the state of each session, including the data access for any row data. - Each physical dolt database in the provider can have the state of multiple branch heads managed by a session. This +* dsess.Session: Responsible for maintaining the state of each session, including the data access for any row data. + Each physical dolt database in the provider can have the state of multiple branch heads managed by a session. This state is loaded on demand from the provider as the client asks for different databases by name, as `dolt_checkout` is called, etc. -* dsess.DoltTransaction: Records a start state (noms root) for each database managed by the transaction. Responsible - for committing new data as the result of a COMMIT or dolt_commit() by merging this start state with session changes +* dsess.DoltTransaction: Records a start state (noms root) for each database managed by the transaction. Responsible + for committing new data as the result of a COMMIT or dolt_commit() by merging this start state with session changes as appropriate. The rough flow of data between the engine and this package: -1) START TRANSACTION calls dsess.Session.StartTransaction() to create a new dsess.DoltTransaction. This transaction +1) START TRANSACTION calls dsess.Session.StartTransaction() to create a new dsess.DoltTransaction. This transaction takes a snapshot of the current noms root for each database known to the provider and records these as part of the transaction. This method clears out all cached state. 2) The engine calls DatabaseProvider.Database() to get a sqle.Database for each database name included in a query, including statements like `USE db`. -3) Databases have access to tables, views, and other schema elements that they provide to the engine upon request as +3) Databases have access to tables, views, and other schema elements that they provide to the engine upon request as part of query analysis, row iteration, etc. As a rule, this data is loaded from the session when asked for. Databases, - tables, views, and other structures in the sqle package are best understood as pass-through entities that always + tables, views, and other structures in the sqle package are best understood as pass-through entities that always defer to the session for their actual data. 4) When actual data is required, a table or other schema element asks the session for the data. The primary interface for this exchange is Session.LookupDbState(), which takes a database name. -5) Eventually, the client session issues a COMMIT or DOLT_COMMIT() statement. This calls Session.CommitTransaction(), +5) Eventually, the client session issues a COMMIT or DOLT_COMMIT() statement. This calls Session.CommitTransaction(), which enforces business logic rules around the commit and then calls DoltTransaction.Commit() to persist the changes. Databases managed by the provider and the session can be referred to by either a base name (myDb) or a fully qualified @@ -55,8 +55,8 @@ name (myDb/myBranch). The details of this are a little bit subtle: b) whatever branch head was last checked out with dolt_checkout(). Changing the branch head referred to by an unqualified database name is the primary purpose of dolt_checkout(). * `mydb/branch` always resolves to that branch head, as it existed at transaction start -* Database names exposed to the engine are always `mydb`, never `mydb/branch`. This includes the result of - `select database()`. This is because the engine expects base database names when e.g. checking GRANTs, returning +* Database names exposed to the engine are always `mydb`, never `mydb/branch`. This includes the result of + `select database()`. This is because the engine expects base database names when e.g. checking GRANTs, returning information the information schema table, etc. * sqle.Database has an external name it exposes to the engine via Name(), as well as an internal name that includes a revision qualifier, RevisionQualifiedName(). The latter should always be used internally when accessing session data, @@ -66,6 +66,6 @@ name (myDb/myBranch). The details of this are a little bit subtle: It's possible to alter the data on multiple HEADS in a single session, but we currently restrict the users to committing a single one. It doesn't need to be the checked out head -- we simply look for a single dirty branch head state and commit that one. If there is more than one, it's an error. We may allow multiple branch heads to be updated -in a single transaction in the future. +in a single transaction in the future. - */ +*/ diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 10ca196079..7bbdb03129 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -141,7 +141,7 @@ func DSessFromSess(sess sql.Session) *DoltSession { // the interface returned by the public method. func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchState, bool, error) { dbName = strings.ToLower(dbName) - + var baseName, rev string baseName, rev = SplitRevisionDbName(dbName) @@ -166,14 +166,14 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta } } - // No state for this db / branch combination yet, look it up from the provider. We use the unqualified DB name (no - // branch) if the current DB has not yet been loaded into this session. It will resolve to that DB's default branch + // No state for this db / branch combination yet, look it up from the provider. We use the unqualified DB name (no + // branch) if the current DB has not yet been loaded into this session. It will resolve to that DB's default branch // in that case. revisionQualifiedName := dbName if rev != "" { revisionQualifiedName = revisionDbName(baseName, rev) } - + database, ok, err := d.provider.SessionDatabase(ctx, revisionQualifiedName) if err != nil { return nil, false, err @@ -215,8 +215,8 @@ func SplitRevisionDbName(dbName string) (string, string) { // LookupDbState returns the session state for the database named. Unqualified database names, e.g. `mydb` get resolved // to the currently checked out HEAD, which could be a branch, a commit, a tag, etc. Revision-qualified database names, // e.g. `mydb/branch1` get resolved to the session state for the revision named. -// A note on unqualified database names: unqualified names will resolve to a) the head last checked out with -// `dolt_checkout`, or b) the database's default branch, if this session hasn't called `dolt_checkout` yet. +// A note on unqualified database names: unqualified names will resolve to a) the head last checked out with +// `dolt_checkout`, or b) the database's default branch, if this session hasn't called `dolt_checkout` yet. // Also returns a bool indicating whether the database was found, and an error if one occurred. func (d *DoltSession) LookupDbState(ctx *sql.Context, dbName string) (SessionState, bool, error) { s, ok, err := d.lookupDbState(ctx, dbName) @@ -306,7 +306,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra txDbs = append(txDbs, db) } } - + return NewDoltTransaction(ctx, txDbs, tCharacteristic) } @@ -370,11 +370,11 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er if len(dirties) == 0 { return nil } - + if len(dirties) > 1 { return ErrDirtyWorkingSets } - + performDoltCommitVar, err := d.Session.GetSessionVariable(ctx, DoltCommitOnTransactionCommit) if err != nil { return err @@ -423,7 +423,7 @@ func (d *DoltSession) dirtyWorkingSets() []*branchState { } } } - + return dirtyStates } @@ -484,10 +484,10 @@ type doCommitFunc func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltd // commitBranchState performs a commit for the branch state given, using the doCommitFunc provided func (d *DoltSession) commitBranchState( - ctx *sql.Context, - branchState *branchState, - tx sql.Transaction, - commitFunc doCommitFunc, + ctx *sql.Context, + branchState *branchState, + tx sql.Transaction, + commitFunc doCommitFunc, ) (*doltdb.Commit, error) { dtx, ok := tx.(*DoltTransaction) if !ok { @@ -498,7 +498,7 @@ func (d *DoltSession) commitBranchState( if err != nil { return nil, err } - + branchState.dirty = false return newCommit, nil } @@ -539,7 +539,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do if !ok { return nil, fmt.Errorf("session state for database %s not found", dbName) } - + return d.newPendingCommit(ctx, branchState, roots, props) } @@ -861,7 +861,7 @@ func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref. if err != nil { return err } - + d.mu.Lock() defer d.mu.Unlock() @@ -874,7 +874,7 @@ func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref. dbState.checkedOutRevSpec = headRef.GetPath() dbState.currRevSpec = headRef.GetPath() dbState.currRevType = RevisionTypeBranch - + return nil } @@ -894,7 +894,7 @@ func (d *DoltSession) SwitchWorkingSet( } d.mu.Lock() - + baseName, _ := SplitRevisionDbName(dbName) dbState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { @@ -908,15 +908,15 @@ func (d *DoltSession) SwitchWorkingSet( d.mu.Unlock() // bootstrap the db state as necessary - _, ok, err = d.lookupDbState(ctx, baseName + DbRevisionDelimiter + headRef.GetPath()) + _, ok, err = d.lookupDbState(ctx, baseName+DbRevisionDelimiter+headRef.GetPath()) if err != nil { return err } - + if !ok { return sql.ErrDatabaseNotFound.New(dbName) } - + return nil } @@ -933,10 +933,10 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { if !ok { return sql.ErrDatabaseNotFound.New(db.Name()) } - + d.mu.Lock() defer d.mu.Unlock() - + // Set the session state for this database according to what database name was USEd // In the case of a revision qualified name, that will be the revision specified // In the case of an unqualified name (USE mydb), this will be the last checked out head in this session. @@ -949,7 +949,7 @@ func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { dbState.currRevSpec = sdb.Revision() dbState.currRevType = sdb.RevisionType() } - + return nil } @@ -1030,7 +1030,7 @@ func (d *DoltSession) setForeignKeyChecksSessionVar(ctx *sql.Context, key string if convertedVal != nil { intVal = convertedVal.(int64) } - + if intVal == 0 { for _, dbState := range d.dbStates { for _, branchState := range dbState.heads { @@ -1088,7 +1088,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } return err } - + sessionState.dbName = baseName sessionState.checkedOutRevSpec = db.Revision() sessionState.currRevType = db.RevisionType() @@ -1098,7 +1098,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { branchState := NewEmptyBranchState(sessionState) sessionState.heads[strings.ToLower(rev)] = branchState d.mu.Unlock() - + // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and // the writer with one that errors out // TODO: this no longer gets called at session creation time, so the error handling below never occurs when a @@ -1150,11 +1150,11 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { // This has to happen after SetWorkingSet above, since it does a stale check before its work branchState.headCommit = dbState.HeadCommit - + if sessionState.Err == nil { return d.setSessionVarsForDb(ctx, db.Name(), branchState) } - + return nil } @@ -1196,11 +1196,11 @@ func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef, if !ok { return nil, sql.ErrDatabaseNotFound.New(dbName) } - + if branchState.dbState.currRevType != RevisionTypeBranch { return nil, doltdb.ErrOperationNotSupportedInDetachedHead } - + return ref.NewBranchRef(branchState.dbState.currRevSpec), nil } @@ -1218,11 +1218,11 @@ func (d *DoltSession) CurrentHead(ctx *sql.Context, dbName string) (string, bool d.mu.Lock() dbState, ok := d.dbStates[baseName] d.mu.Unlock() - + if ok { return dbState.currRevSpec, true, nil } - + return "", false, nil } @@ -1241,7 +1241,7 @@ func (d *DoltSession) BatchMode() batchMode { // setSessionVarsForDb updates the three session vars that track the value of the session root hashes func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state *branchState) error { baseName, _ := SplitRevisionDbName(dbName) - + // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here if state.WorkingSet() != nil { @@ -1575,4 +1575,4 @@ func TransactionRoot(ctx *sql.Context, db SqlDatabase) (hash.Hash, error) { } return nomsRoot, nil -} \ No newline at end of file +} diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index 70b7a764f0..30f25b4e03 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -38,16 +38,16 @@ type RevisionDatabase interface { Revision() string // RevisionType returns the type of revision this database is pinned to. RevisionType() RevisionType - // RevisionQualifiedName returns the fully qualified name of the database, which includes the revision if one is + // RevisionQualifiedName returns the fully qualified name of the database, which includes the revision if one is // specified. RevisionQualifiedName() string - // RequestedName returns the name of the database as requested by the user when the name was resolved to this + // RequestedName returns the name of the database as requested by the user when the name was resolved to this // database. RequestedName() string - // Versioned returns whether this database implementation supports more than a single revision. + // Versioned returns whether this database implementation supports more than a single revision. // TODO: This shouldn't be a necessary part of the interface, but it's required to differentiate between dolt-backed // databases and others that we serve for custom purposes with similar pieces of functionality, and the session - // management logic intermixes these concerns. + // management logic intermixes these concerns. Versioned() bool } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index d53b3f0f6e..cc79595061 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -91,11 +91,11 @@ type savepoint struct { } func NewDoltTransaction( - ctx *sql.Context, - dbs []SqlDatabase, - tCharacteristic sql.TransactionCharacteristic, + ctx *sql.Context, + dbs []SqlDatabase, + tCharacteristic sql.TransactionCharacteristic, ) (*DoltTransaction, error) { - + startPoints := make(map[string]dbRoot) for _, db := range dbs { nomsRoot, err := db.DbData().Ddb.NomsRoot(ctx) @@ -125,7 +125,7 @@ func (tx DoltTransaction) IsReadOnly() bool { return tx.tCharacteristic == sql.ReadOnly } -// GetInitialRoot returns the noms root hash for the db named, established when the transaction began. The dbName here +// GetInitialRoot returns the noms root hash for the db named, established when the transaction began. The dbName here // is always the base name of the database, not the revision qualified one. func (tx DoltTransaction) GetInitialRoot(dbName string) (hash.Hash, bool) { startPoint, ok := tx.dbStartPoints[strings.ToLower(dbName)] @@ -160,13 +160,13 @@ type transactionWrite func(ctx *sql.Context, // doltCommit is a transactionWrite function that updates the working set and commits a pending commit atomically func doltCommit(ctx *sql.Context, - tx *DoltTransaction, // the transaction being written - doltDb *doltdb.DoltDB, // the database to write to - startState *doltdb.WorkingSet, // the starting working set - commit *doltdb.PendingCommit, // optional - workingSet *doltdb.WorkingSet, // must be provided - currHash hash.Hash, // hash of the current working set to be written - mergeOpts editor.Options, // editor options for merges + tx *DoltTransaction, // the transaction being written + doltDb *doltdb.DoltDB, // the database to write to + startState *doltdb.WorkingSet, // the starting working set + commit *doltdb.PendingCommit, // optional + workingSet *doltdb.WorkingSet, // must be provided + currHash hash.Hash, // hash of the current working set to be written + mergeOpts editor.Options, // editor options for merges ) (*doltdb.WorkingSet, *doltdb.Commit, error) { pending := *commit @@ -209,7 +209,7 @@ func doltCommit(ctx *sql.Context, // updates). The merged root value becomes our new Staged root value which // is the value which we are trying to commit. start := time.Now() - + result, err := merge.MergeRoots( ctx, pending.Roots.Staged, @@ -241,13 +241,13 @@ func doltCommit(ctx *sql.Context, // txCommit is a transactionWrite function that updates the working set func txCommit(ctx *sql.Context, - tx *DoltTransaction, // the transaction being written - doltDb *doltdb.DoltDB, // the database to write to - _ *doltdb.WorkingSet, // the starting working set - _ *doltdb.PendingCommit, // optional - workingSet *doltdb.WorkingSet, // must be provided - hash hash.Hash, // hash of the current working set to be written - _ editor.Options, // editor options for merges + tx *DoltTransaction, // the transaction being written + doltDb *doltdb.DoltDB, // the database to write to + _ *doltdb.WorkingSet, // the starting working set + _ *doltdb.PendingCommit, // optional + workingSet *doltdb.WorkingSet, // must be provided + hash hash.Hash, // hash of the current working set to be written + _ editor.Options, // editor options for merges ) (*doltdb.WorkingSet, *doltdb.Commit, error) { var rsc doltdb.ReplicationStatusController err := doltDb.UpdateWorkingSet(ctx, workingSet.Ref(), workingSet, hash, tx.getWorkingSetMeta(ctx), &rsc) @@ -257,10 +257,10 @@ func txCommit(ctx *sql.Context, // DoltCommit commits the working set and creates a new DoltCommit as specified, in one atomic write func (tx *DoltTransaction) DoltCommit( - ctx *sql.Context, - workingSet *doltdb.WorkingSet, - commit *doltdb.PendingCommit, - dbName string, + ctx *sql.Context, + workingSet *doltdb.WorkingSet, + commit *doltdb.PendingCommit, + dbName string, ) (*doltdb.WorkingSet, *doltdb.Commit, error) { return tx.doCommit(ctx, workingSet, commit, doltCommit, dbName) } @@ -332,11 +332,11 @@ func WaitForReplicationController(ctx *sql.Context, rsc doltdb.ReplicationStatus // doCommit commits this transaction with the write function provided. It takes the same params as DoltCommit func (tx *DoltTransaction) doCommit( - ctx *sql.Context, - workingSet *doltdb.WorkingSet, - commit *doltdb.PendingCommit, - writeFn transactionWrite, - dbName string, + ctx *sql.Context, + workingSet *doltdb.WorkingSet, + commit *doltdb.PendingCommit, + writeFn transactionWrite, + dbName string, ) (*doltdb.WorkingSet, *doltdb.Commit, error) { sess := DSessFromSess(ctx.Session) branchState, ok, err := sess.lookupDbState(ctx, dbName) @@ -353,14 +353,14 @@ func (tx *DoltTransaction) doCommit( if !ok { return nil, nil, fmt.Errorf("database %s unknown to transaction, this is a bug", dbName) } - + startState, err := startPoint.db.ResolveWorkingSetAtRoot(ctx, workingSet.Ref(), startPoint.rootHash) if err != nil { return nil, nil, err } - + // TODO: no-op if the working set hasn't changed since the transaction started - + mergeOpts := branchState.EditOpts() for i := 0; i < maxTxCommitRetries; i++ { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index eb8517974e..c75916ddbf 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -116,7 +116,7 @@ func TestSingleQuery(t *testing.T) { // Convenience test for debugging a single query. Unskip and set to the desired query. func TestSingleScript(t *testing.T) { t.Skip() - + var script = queries.ScriptTest{ Name: "CALL DOLT_MERGE ff correctly works with autocommit off", SetUpScript: []string{ @@ -264,7 +264,7 @@ func TestSingleQueryPrepared(t *testing.T) { func TestSingleScriptPrepared(t *testing.T) { t.Skip() - + var script = queries.ScriptTest{ Name: "dolt_history table filter correctness", SetUpScript: []string{ diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index a6519e2c1f..8c85d71c76 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -1972,7 +1972,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{1, 1}}, }, { - Query: "call dolt_checkout('b2');", + Query: "call dolt_checkout('b2');", SkipResultsCheck: true, }, { @@ -1984,7 +1984,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{2, 2}}, }, { - Query: "call dolt_checkout('b3');", + Query: "call dolt_checkout('b3');", SkipResultsCheck: true, }, { @@ -1996,7 +1996,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{3, 3}}, }, { - Query: "call dolt_checkout('main');", + Query: "call dolt_checkout('main');", SkipResultsCheck: true, }, { @@ -2036,7 +2036,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{1, 1}}, }, { - Query: "use `mydb/b2`;", + Query: "use `mydb/b2`;", SkipResultsCheck: true, }, { @@ -2048,7 +2048,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{2, 2}}, }, { - Query: "use `mydb/b3`;", + Query: "use `mydb/b3`;", SkipResultsCheck: true, }, { @@ -2060,7 +2060,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{3, 3}}, }, { - Query: "use `mydb/main`", + Query: "use `mydb/main`", SkipResultsCheck: true, }, { @@ -2072,7 +2072,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{1, 1}}, }, { - Query: "use `mydb`", + Query: "use `mydb`", SkipResultsCheck: true, }, { @@ -2084,11 +2084,11 @@ var DoltCheckoutScripts = []queries.ScriptTest{ Expected: []sql.Row{{1, 1}}, }, { - Query: "call dolt_checkout('b2');", + Query: "call dolt_checkout('b2');", SkipResultsCheck: true, }, { - Query: "use `mydb/b3`", + Query: "use `mydb/b3`", SkipResultsCheck: true, }, { @@ -2097,7 +2097,7 @@ var DoltCheckoutScripts = []queries.ScriptTest{ }, // Since b2 was the last branch checked out with dolt_checkout, it's what mydb resolves to { - Query: "use `mydb`", + Query: "use `mydb`", SkipResultsCheck: true, }, { @@ -2394,7 +2394,7 @@ var LogTableFunctionScriptTests = []queries.ScriptTest{ // "call dolt_add('.')", // "set @Commit1 = '';", // "call dolt_commit_hash_out(@Commit1, '-am', 'creating table t');", - // + // // "insert into t values(1, 'one', 'two'), (2, 'two', 'three');", // "set @Commit2 = '';", // "call dolt_commit_hash_out(@Commit2, '-am', 'inserting into t');", diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index bf2694b3ab..4eb501e3c7 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -209,11 +209,11 @@ var MergeScripts = []queries.ScriptTest{ Expected: []sql.Row{{"add some more values"}}, }, { - Query: "CALL DOLT_CHECKOUT('-b', 'other')", + Query: "CALL DOLT_CHECKOUT('-b', 'other')", Expected: []sql.Row{{0}}, }, { - Query: "CALL DOLT_CHECKOUT('main')", + Query: "CALL DOLT_CHECKOUT('main')", Expected: []sql.Row{{0}}, }, }, @@ -300,7 +300,7 @@ var MergeScripts = []queries.ScriptTest{ }, { // errors because creating a new branch implicitly commits the current transaction - Query: "CALL DOLT_CHECKOUT('-b', 'other-branch')", + Query: "CALL DOLT_CHECKOUT('-b', 'other-branch')", ExpectedErrStr: "Merge conflict detected, transaction rolled back. Merge conflicts must be resolved using the dolt_conflicts tables before committing a transaction. To commit transactions with merge conflicts, set @@dolt_allow_commit_conflicts = 1", }, }, @@ -358,11 +358,11 @@ var MergeScripts = []queries.ScriptTest{ Expected: []sql.Row{{1, 0}}, }, { - Query: "CALL DOLT_CHECKOUT('-b', 'other')", + Query: "CALL DOLT_CHECKOUT('-b', 'other')", Expected: []sql.Row{{0}}, }, { - Query: "CALL DOLT_CHECKOUT('main')", + Query: "CALL DOLT_CHECKOUT('main')", Expected: []sql.Row{{0}}, }, { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index e465686ce0..7ac99ec575 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -408,11 +408,11 @@ var DropDatabaseMultiSessionScriptTests = []queries.ScriptTest{ Query: "/* client b */ select database();", Expected: []sql.Row{{"db01"}}, }, - // TODO: this could be better: there's no longer a branch branch1, and we lose track of the fact that we were on - // branch1 when the `drop database` is processed -- as far as the engine is concerned we are using a database + // TODO: this could be better: there's no longer a branch branch1, and we lose track of the fact that we were on + // branch1 when the `drop database` is processed -- as far as the engine is concerned we are using a database // called `db01`, no branch info. It's enough for now to not panic in this edge case. { - Query: "/* client b */ show tables;", + Query: "/* client b */ show tables;", Expected: []sql.Row{}, }, }, diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 84640289de..2b7cf64a4f 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2439,7 +2439,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "call dolt_checkout('b1')", + Query: "call dolt_checkout('b1')", SkipResultsCheck: true, }, { @@ -2453,7 +2453,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "call dolt_checkout('main')", + Query: "call dolt_checkout('main')", SkipResultsCheck: true, }, { @@ -2632,7 +2632,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "commit", + Query: "commit", ExpectedErrStr: "Cannot commit changes on more than one branch / database", }, }, @@ -2654,7 +2654,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "call dolt_checkout('b1')", + Query: "call dolt_checkout('b1')", SkipResultsCheck: true, }, { @@ -2664,7 +2664,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "commit", + Query: "commit", ExpectedErrStr: "Cannot commit changes on more than one branch / database", }, }, @@ -2693,7 +2693,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "commit", + Query: "commit", ExpectedErrStr: "Cannot commit changes on more than one branch / database", }, }, From 3a56ec0678afa6ca6adcc9905ddd35bd3e60bd3a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 23 May 2023 12:43:19 -0700 Subject: [PATCH 084/167] Fixed default branch handling --- go/cmd/dolt/commands/sqlserver/server_test.go | 164 ++++++++++-------- .../doltcore/sqle/database_provider.go | 50 ++++-- 2 files changed, 130 insertions(+), 84 deletions(-) diff --git a/go/cmd/dolt/commands/sqlserver/server_test.go b/go/cmd/dolt/commands/sqlserver/server_test.go index 0897540733..429911d826 100644 --- a/go/cmd/dolt/commands/sqlserver/server_test.go +++ b/go/cmd/dolt/commands/sqlserver/server_test.go @@ -50,7 +50,7 @@ type testPerson struct { Title string } -type testBranch struct { +type testResult struct { Branch string } @@ -297,6 +297,12 @@ func TestServerFailsIfPortInUse(t *testing.T) { wg.Wait() } +type defaultBranchTest struct { + query *dbr.SelectStmt + expectedRes []testResult + expectedErrStr string +} + func TestServerSetDefaultBranch(t *testing.T) { dEnv, err := sqle.CreateEnvWithSeedData() require.NoError(t, err) @@ -316,114 +322,126 @@ func TestServerSetDefaultBranch(t *testing.T) { const dbName = "dolt" + defaultBranch := env.DefaultInitBranch + conn, err := dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) require.NoError(t, err) sess := conn.NewSession(nil) - defaultBranch := env.DefaultInitBranch - - tests := []struct { - query *dbr.SelectStmt - expectedRes []testBranch - }{ + tests := []defaultBranchTest { { - query: sess.Select("active_branch() as branch"), - expectedRes: []testBranch{{defaultBranch}}, - }, - { - query: sess.SelectBySql("set GLOBAL dolt_default_branch = 'refs/heads/new'"), - expectedRes: []testBranch{}, - }, - { - query: sess.Select("active_branch() as branch"), - expectedRes: []testBranch{{defaultBranch}}, + query: sess.SelectBySql("select active_branch() as branch"), + expectedRes: []testResult{{defaultBranch}}, }, { query: sess.SelectBySql("call dolt_checkout('-b', 'new')"), - expectedRes: []testBranch{{""}}, + expectedRes: []testResult{{""}}, + }, + { + query: sess.SelectBySql("call dolt_checkout('-b', 'new2')"), + expectedRes: []testResult{{""}}, + }, + } + + runDefaultBranchTests(t, tests, conn) + + conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) + require.NoError(t, err) + sess = conn.NewSession(nil) + + tests = []defaultBranchTest { + { + query: sess.SelectBySql("select active_branch() as branch"), + expectedRes: []testResult{{defaultBranch}}, + }, + { + query: sess.SelectBySql("set GLOBAL dolt_default_branch = 'refs/heads/new'"), + expectedRes: nil, + }, + { + query: sess.SelectBySql("select active_branch() as branch"), + expectedRes: []testResult{{"main"}}, }, { query: sess.SelectBySql("call dolt_checkout('main')"), - expectedRes: []testBranch{{""}}, + expectedRes: []testResult{{""}}, }, } - for _, test := range tests { - t.Run(test.query.Query, func(t *testing.T) { - var branch []testBranch - _, err := test.query.LoadContext(context.Background(), &branch) - assert.NoError(t, err) - assert.ElementsMatch(t, branch, test.expectedRes) - }) - } - conn.Close() + runDefaultBranchTests(t, tests, conn) conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) require.NoError(t, err) - defer conn.Close() - sess = conn.NewSession(nil) - tests = []struct { - query *dbr.SelectStmt - expectedRes []testBranch - }{ + tests = []defaultBranchTest{ { - query: sess.Select("active_branch() as branch"), - expectedRes: []testBranch{{"new"}}, + query: sess.SelectBySql("select active_branch() as branch"), + expectedRes: []testResult{{"new"}}, }, { - query: sess.SelectBySql("set GLOBAL dolt_default_branch = 'new'"), - expectedRes: []testBranch{}, + query: sess.SelectBySql("set GLOBAL dolt_default_branch = 'new2'"), + expectedRes: nil, }, } - - defer func(sess *dbr.Session) { - var res []struct { - int - } - sess.SelectBySql("set GLOBAL dolt_default_branch = ''").LoadContext(context.Background(), &res) - }(sess) - - for _, test := range tests { - t.Run(test.query.Query, func(t *testing.T) { - var branch []testBranch - _, err := test.query.LoadContext(context.Background(), &branch) - assert.NoError(t, err) - assert.ElementsMatch(t, branch, test.expectedRes) - }) - } - conn.Close() + + runDefaultBranchTests(t, tests, conn) conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) require.NoError(t, err) - defer conn.Close() - sess = conn.NewSession(nil) - tests = []struct { - query *dbr.SelectStmt - expectedRes []testBranch - }{ + tests = []defaultBranchTest{ { - query: sess.Select("active_branch() as branch"), - expectedRes: []testBranch{{"new"}}, + query: sess.SelectBySql("select active_branch() as branch"), + expectedRes: []testResult{{"new2"}}, }, } - for _, test := range tests { - t.Run(test.query.Query, func(t *testing.T) { - var branch []testBranch - _, err := test.query.LoadContext(context.Background(), &branch) - assert.NoError(t, err) - assert.ElementsMatch(t, branch, test.expectedRes) - }) + runDefaultBranchTests(t, tests, conn) + + conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) + require.NoError(t, err) + sess = conn.NewSession(nil) + + tests = []defaultBranchTest{ + { + query: sess.SelectBySql("set GLOBAL dolt_default_branch = 'doesNotExist'"), + expectedRes: nil, + }, } - var res []struct { - int + runDefaultBranchTests(t, tests, conn) + + conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) + require.NoError(t, err) + sess = conn.NewSession(nil) + + tests = []defaultBranchTest{ + { + query: sess.SelectBySql("select active_branch() as branch"), + expectedErrStr: "database not found", // TODO: should be a better error message + }, } - sess.SelectBySql("set GLOBAL dolt_default_branch = ''").LoadContext(context.Background(), &res) + + runDefaultBranchTests(t, tests, conn) +} + +func runDefaultBranchTests(t *testing.T, tests []defaultBranchTest, conn *dbr.Connection) { + for _, test := range tests { + t.Run(test.query.Query, func(t *testing.T) { + var branch []testResult + _, err := test.query.LoadContext(context.Background(), &branch) + if test.expectedErrStr != "" { + require.Error(t, err) + assert.Containsf(t, err.Error(), test.expectedErrStr, "expected error string not found") + } else { + require.NoError(t, err) + assert.Equal(t, test.expectedRes, branch) + } + }) + } + require.NoError(t, conn.Close()) } func TestReadReplica(t *testing.T) { diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index e42e378cbe..cd67807856 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -21,8 +21,6 @@ import ( "strings" "sync" - "github.com/dolthub/go-mysql-server/sql" - "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/dolt/go/libraries/doltcore/dbfactory" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" @@ -37,6 +35,7 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/table/editor" "github.com/dolthub/dolt/go/libraries/utils/filesys" "github.com/dolthub/dolt/go/store/types" + "github.com/dolthub/go-mysql-server/sql" ) type DoltDatabaseProvider struct { @@ -1062,23 +1061,44 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds // Convert to a revision database before returning. If we got a non-qualified name, convert it to a qualified name // using the session's current head revisionQualifiedName := name + usingDefaultBranch := false + head := "" if !isRevisionDbName { sess := dsess.DSessFromSess(ctx.Session) - // A newly created session may not have any info on current head stored yet, in which case we get the default - // branch for the db itself instead. - head, ok, err := sess.CurrentHead(ctx, baseName) + var err error + head, ok, err = sess.CurrentHead(ctx, baseName) if err != nil { return nil, false, err } + // A newly created session may not have any info on current head stored yet, in which case we get the default + // branch for the db itself instead. if !ok { - rsr := db.DbData().Rsr - headRef, err := rsr.CWBHeadRef() - if err != nil { - return nil, false, err + usingDefaultBranch = true + + // First check the global variable for the default branch + _, val, ok := sql.SystemVariables.GetGlobal(dsess.DefaultBranchKey(db.Name())) + if ok { + head = val.(string) + branchRef, err := ref.Parse(head) + if err == nil { + head = branchRef.GetPath() + } else { + head = "" + // continue to below + } + } + + // Fall back to the database's checked out branch + if head == "" { + rsr := db.DbData().Rsr + headRef, err := rsr.CWBHeadRef() + if err != nil { + return nil, false, err + } + head = headRef.GetPath() } - head = headRef.GetPath() } revisionQualifiedName = baseName + dsess.DbRevisionDelimiter + head @@ -1086,8 +1106,16 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds db, ok, err := p.databaseForRevision(ctx, revisionQualifiedName, name) if err != nil { - return nil, false, err + if sql.ErrDatabaseNotFound.Is(err) && usingDefaultBranch { + // We can return a better error message here in some cases + // TODO: this better error message doesn't always get returned to clients because the code path is doesn't + // return an error, only a boolean result (HasDB) + return nil, false, fmt.Errorf("cannot resolve default branch head for database '%s': '%s'", baseName, head) + } else { + return nil, false, err + } } + if !ok { return nil, false, nil } From a9cfd5b5e577db937537e33168a846d044c33b7c Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 23 May 2023 16:58:09 -0700 Subject: [PATCH 085/167] Fix for missing db session vars before first db reference --- go/libraries/doltcore/sqle/dsess/session.go | 23 ++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 7bbdb03129..fb921e881f 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -307,7 +307,28 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - return NewDoltTransaction(ctx, txDbs, tCharacteristic) + tx, err := NewDoltTransaction(ctx, txDbs, tCharacteristic) + if err != nil { + return nil, err + } + + // Set session vars for every DB in this session using their current branch head + for _, db := range doltDatabases { + bs, ok, err := d.lookupDbState(ctx, db.Name()) + if err != nil { + return nil, err + } + if !ok { + return nil, fmt.Errorf("unable to find session state for database %s", db.Name()) + } + + err = d.setSessionVarsForDb(ctx, db.Name(), bs) + if err != nil { + return nil, err + } + } + + return tx, err } // clear clears all DB state for this session From 63559daa3ea4046291e276725f2a8b69d3fd4007 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 23 May 2023 17:09:36 -0700 Subject: [PATCH 086/167] Fixed dolt_transaction_commit test -- previous code was apparently generating an extra spurious commit and the test expected this --- .../dolt_transaction_commit_test.go | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go index 74757d14f1..327f839068 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go @@ -384,35 +384,30 @@ func TestDoltTransactionCommitAutocommit(t *testing.T) { if !ok { t.Fatal("'mydb' database not found") } - cs, err := doltdb.NewCommitSpec("HEAD") + + headSpec, err := doltdb.NewCommitSpec("HEAD") require.NoError(t, err) headRefs, err := db.GetHeadRefs(context.Background()) require.NoError(t, err) - commit3, err := db.Resolve(context.Background(), cs, headRefs[0]) + head, err := db.Resolve(context.Background(), headSpec, headRefs[0]) require.NoError(t, err) - cm3, err := commit3.GetCommitMeta(context.Background()) + headMeta, err := head.GetCommitMeta(context.Background()) require.NoError(t, err) - require.Contains(t, cm3.Description, "Transaction commit") + require.Contains(t, headMeta.Description, "Transaction commit") - as, err := doltdb.NewAncestorSpec("~1") + ancestorSpec, err := doltdb.NewAncestorSpec("~1") require.NoError(t, err) - commit2, err := commit3.GetAncestor(context.Background(), as) + parent, err := head.GetAncestor(context.Background(), ancestorSpec) require.NoError(t, err) - cm2, err := commit2.GetCommitMeta(context.Background()) + parentMeta, err := parent.GetCommitMeta(context.Background()) require.NoError(t, err) - require.Contains(t, cm2.Description, "Transaction commit") + require.Contains(t, parentMeta.Description, "Transaction commit") - commit1, err := commit2.GetAncestor(context.Background(), as) + grandParent, err := parent.GetAncestor(context.Background(), ancestorSpec) require.NoError(t, err) - cm1, err := commit1.GetCommitMeta(context.Background()) + grandparentMeta, err := grandParent.GetCommitMeta(context.Background()) require.NoError(t, err) - require.Equal(t, "Transaction commit", cm1.Description) - - commit0, err := commit1.GetAncestor(context.Background(), as) - require.NoError(t, err) - cm0, err := commit0.GetCommitMeta(context.Background()) - require.NoError(t, err) - require.Equal(t, "checkpoint enginetest database mydb", cm0.Description) + require.Equal(t, "checkpoint enginetest database mydb", grandparentMeta.Description) } func TestDoltTransactionCommitLateFkResolution(t *testing.T) { From 3d1aca39e406aaa22c314d4ee8cf10240de2e4e8 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 23 May 2023 17:28:26 -0700 Subject: [PATCH 087/167] Fixed a couple tests --- integration-tests/bats/config.bats | 2 +- integration-tests/bats/db-revision-specifiers.bats | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration-tests/bats/config.bats b/integration-tests/bats/config.bats index 87d0e275cf..bf6104405c 100644 --- a/integration-tests/bats/config.bats +++ b/integration-tests/bats/config.bats @@ -189,7 +189,7 @@ teardown() { } @test "config: SQL can create databases with no user and email set" { - dolt sql -b -q " + dolt sql -q " CREATE DATABASE testdb; use testdb; CREATE TABLE test (pk int primary key, c1 varchar(1));" diff --git a/integration-tests/bats/db-revision-specifiers.bats b/integration-tests/bats/db-revision-specifiers.bats index d27f8de8eb..7342bc1428 100644 --- a/integration-tests/bats/db-revision-specifiers.bats +++ b/integration-tests/bats/db-revision-specifiers.bats @@ -44,7 +44,7 @@ use $database_name/branch1; show databases; SQL [ "$status" -eq "0" ] - [[ "$output" =~ "$database_name/branch1" ]] || false + [[ "$output" =~ "$database_name" ]] || false # Can be used as part of a fully qualified table name run dolt sql -q "SELECT * FROM \`$database_name/branch1\`.test" -r=csv @@ -80,7 +80,7 @@ use $database_name/v1; show databases; SQL [ "$status" -eq "0" ] - [[ "$output" =~ "$database_name/v1" ]] || false + [[ "$output" =~ "$database_name" ]] || false # Can be used as part of a fully qualified table name run dolt sql -q "SELECT * FROM \`$database_name/v1\`.test" -r=csv @@ -95,7 +95,7 @@ use $database_name/v1; insert into test values (100, 'beige'); SQL [ "$status" -ne "0" ] - [[ "$output" =~ "$database_name/v1 is read-only" ]] || false + [[ "$output" =~ "$database_name is read-only" ]] || false } @test "db-revision-specifiers: commit-qualified database revisions" { @@ -118,7 +118,7 @@ use $database_name/$commit; show databases; SQL [ "$status" -eq "0" ] - [[ "$output" =~ "$database_name/$commit" ]] || false + [[ "$output" =~ "$database_name" ]] || false # Can be used as part of a fully qualified table name run dolt sql -q "SELECT * FROM \`$database_name/$commit\`.test" -r=csv @@ -133,5 +133,5 @@ use $database_name/$commit; insert into test values (100, 'beige'); SQL [ "$status" -ne "0" ] - [[ "$output" =~ "$database_name/$commit is read-only" ]] || false + [[ "$output" =~ "$database_name is read-only" ]] || false } From 06dfba0e1976d144198db2451a6a6e8f42032b8b Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 11:06:39 -0700 Subject: [PATCH 088/167] Bug fix for bad branch. Fixed tests. --- go/libraries/doltcore/sqle/dsess/session.go | 21 ++++++-------------- integration-tests/bats/deleted-branches.bats | 20 ++++++++++--------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index fb921e881f..f35f26d4bf 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -314,18 +314,15 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // Set session vars for every DB in this session using their current branch head for _, db := range doltDatabases { + // faulty settings can make it impossible to load particular DB branch states, so we ignore any errors in this + // loop and just decline to set the session vars. Throwing an error on transaction start in these cases makes it + // impossible for the user to correct any problems. bs, ok, err := d.lookupDbState(ctx, db.Name()) - if err != nil { - return nil, err - } - if !ok { - return nil, fmt.Errorf("unable to find session state for database %s", db.Name()) + if err != nil || !ok { + continue } - err = d.setSessionVarsForDb(ctx, db.Name(), bs) - if err != nil { - return nil, err - } + _ = d.setSessionVarsForDb(ctx, db.Name(), bs) } return tx, err @@ -343,12 +340,6 @@ func (d *DoltSession) clear() { } } -// isNoOpTransactionDatabase returns whether the database name given is a non-Dolt database that shouldn't have -// transaction logic performed on it -func isNoOpTransactionDatabase(dbName string) bool { - return len(dbName) == 0 || dbName == "information_schema" || dbName == "mysql" -} - func (d *DoltSession) newWorkingSetForHead(ctx *sql.Context, wsRef ref.WorkingSetRef, dbName string) (*doltdb.WorkingSet, error) { dbData, _ := d.GetDbData(nil, dbName) diff --git a/integration-tests/bats/deleted-branches.bats b/integration-tests/bats/deleted-branches.bats index 25cb41bf34..adf9bc3a4e 100644 --- a/integration-tests/bats/deleted-branches.bats +++ b/integration-tests/bats/deleted-branches.bats @@ -62,7 +62,7 @@ force_delete_main_branch_on_sqlserver() { run dolt sql-client --use-db "dolt_repo_$$" -u dolt -P $PORT \ -q "call dolt_checkout('to_keep');" [ $status -ne 0 ] - [[ "$output" =~ "branch not found" ]] || false + [[ "$output" =~ "database not found" ]] || false } @test "deleted-branches: dolt branch from the CLI does not allow deleting the last branch" { @@ -144,10 +144,11 @@ force_delete_main_branch_on_sqlserver() { # We are able to use a database branch revision in the connection string dolt sql-client --use-db "dolt_repo_$$/main" -u dolt -P $PORT -q "SELECT * FROM test;" - # Trying to checkout a new branch throws an error, but doesn't panic - run dolt sql-client --use-db "dolt_repo_$$/main" -u dolt -P $PORT -q "CALL DOLT_CHECKOUT('to_keep');" - [ $status -ne 0 ] - [[ "$output" =~ "branch not found" ]] || false + # Trying to checkout a new branch works + dolt sql-client --use-db "dolt_repo_$$/main" -u dolt -P $PORT -q "CALL DOLT_CHECKOUT('to_keep');" + + run dolt branch + [[ "$output" =~ "to_keep" ]] || false } @test "deleted-branches: dolt_checkout() from sql-server doesn't panic when connected to a revision db and the db's default branch is invalid" { @@ -159,10 +160,11 @@ force_delete_main_branch_on_sqlserver() { # We are able to use a database branch revision in the connection string dolt sql-client --use-db "dolt_repo_$$/to_keep" -u dolt -P $PORT -q "SELECT * FROM test;" - # Trying to checkout a new branch throws an error, but doesn't panic - run dolt sql-client --use-db "dolt_repo_$$/to_keep" -u dolt -P $PORT -q "CALL DOLT_CHECKOUT('to_checkout');" - [ $status -ne 0 ] - [[ "$output" =~ "branch not found" ]] || false + # Trying to checkout a new branch works + dolt sql-client --use-db "dolt_repo_$$/to_keep" -u dolt -P $PORT -q "CALL DOLT_CHECKOUT('to_checkout');" + + run dolt branch + [[ "$output" =~ "to_checkout" ]] || false } @test "deleted-branches: dolt_checkout() from sql-server works when the db's default branch is invalid, but the global default_branch var is valid" { From 723146f3c9fc620224f31c3c7690a90c983249c1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 12:07:33 -0700 Subject: [PATCH 089/167] Fixed test --- integration-tests/bats/remotes-sql-server.bats | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-tests/bats/remotes-sql-server.bats b/integration-tests/bats/remotes-sql-server.bats index 47f6b9c060..de1a3603ce 100644 --- a/integration-tests/bats/remotes-sql-server.bats +++ b/integration-tests/bats/remotes-sql-server.bats @@ -318,7 +318,8 @@ teardown() { cd repo1 dolt checkout -b feature-branch - dolt commit -am "new commit" + dolt sql -q "create table newTable (a int primary key)" + dolt commit -Am "new commit" dolt push remote1 feature-branch cd ../repo2 @@ -333,8 +334,7 @@ teardown() { # Can't connect to a specific branch with dolt sql-client run dolt sql-client --use-db "repo2/feature-branch" -u dolt -P $PORT -q "SHOW Tables" [ $status -eq 0 ] - [[ $output =~ "feature-branch" ]] || false - [[ $output =~ "test" ]] || false + [[ $output =~ "newTable" ]] || false } @test "remotes-sql-server: connect to hash works" { From a8376e620f7e69f76e0ed1bfe252d652538389f3 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 12:07:58 -0700 Subject: [PATCH 090/167] Fixed problems with faulty replicas --- go/cmd/dolt/commands/engine/utils.go | 1 + go/libraries/doltcore/sqle/database_provider.go | 3 ++- go/libraries/doltcore/sqle/read_replica_database.go | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/cmd/dolt/commands/engine/utils.go b/go/cmd/dolt/commands/engine/utils.go index 1f549adaf9..f38ed4a49f 100644 --- a/go/cmd/dolt/commands/engine/utils.go +++ b/go/cmd/dolt/commands/engine/utils.go @@ -135,6 +135,7 @@ func newReplicaDatabase(ctx context.Context, name string, remoteName string, dEn return sqle.ReadReplicaDatabase{}, err } cli.Println(err) + // TODO: fix this, we should log warnings and return a normal database in this case, not a broken replica db return sqle.ReadReplicaDatabase{Database: db}, nil } return rrd, nil diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index a240edafc8..161283c71d 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -733,7 +733,8 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual switch dbType { case dsess.RevisionTypeBranch: // fetch the upstream head if this is a replicated db - if replicaDb, ok := srcDb.(ReadReplicaDatabase); ok { + replicaDb, ok := srcDb.(ReadReplicaDatabase); + if ok && replicaDb.ValidReplicaState(ctx) { // TODO move this out of analysis phase, should only happen at read time, when the transaction begins (like is // the case with a branch that already exists locally) err := p.ensureReplicaHeadExists(ctx, resolvedRevSpec, replicaDb) diff --git a/go/libraries/doltcore/sqle/read_replica_database.go b/go/libraries/doltcore/sqle/read_replica_database.go index 1cb591e3ef..805c3ac349 100644 --- a/go/libraries/doltcore/sqle/read_replica_database.go +++ b/go/libraries/doltcore/sqle/read_replica_database.go @@ -53,8 +53,6 @@ var _ dsess.RemoteReadReplicaDatabase = ReadReplicaDatabase{} var ErrFailedToLoadReplicaDB = errors.New("failed to load replica database") var ErrInvalidReplicateHeadsSetting = errors.New("invalid replicate heads setting") -var ErrFailedToCastToReplicaDb = errors.New("failed to cast to ReadReplicaDatabase") -var ErrCannotCreateReplicaRevisionDbForCommit = errors.New("cannot create replica revision db for commit") var EmptyReadReplica = ReadReplicaDatabase{} From b3f3f90740cab21c5c01dfd0121829645911350a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 12:18:14 -0700 Subject: [PATCH 091/167] Better error messages for filter branch tests --- go/libraries/doltcore/rebase/filter_branch_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/go/libraries/doltcore/rebase/filter_branch_test.go b/go/libraries/doltcore/rebase/filter_branch_test.go index 5f15eabd44..3b1088910e 100644 --- a/go/libraries/doltcore/rebase/filter_branch_test.go +++ b/go/libraries/doltcore/rebase/filter_branch_test.go @@ -231,12 +231,13 @@ func testFilterBranch(t *testing.T, test filterBranchTest) { require.Equal(t, 0, exitCode) } - root, err := dEnv.WorkingRoot(ctx) - require.NoError(t, err) + t.Run(a.query, func(t *testing.T) { + root, err := dEnv.WorkingRoot(ctx) + require.NoError(t, err) - actRows, err := sqle.ExecuteSelect(dEnv, root, a.query) - require.NoError(t, err) - - require.Equal(t, a.rows, actRows) + actRows, err := sqle.ExecuteSelect(dEnv, root, a.query) + require.NoError(t, err) + require.Equal(t, a.rows, actRows) + }) } } From 6fe9837d16a0c26729915441e1c10f1b973ab1a1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 13:03:07 -0700 Subject: [PATCH 092/167] Bug fix for filter-branch --- go/libraries/doltcore/sqle/dsess/session.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index f35f26d4bf..0ea1f8a7d3 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -273,6 +273,12 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { // StartTransaction refreshes the state of this session and starts a new transaction. func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.TransactionCharacteristic) (sql.Transaction, error) { + // TODO: this is only necessary to support filter-branch, which needs to set a root directly and not have the + // session state altered when a transaction begins + if TransactionsDisabled(ctx) { + return DisabledTransaction{}, nil + } + // New transaction, clear all session state d.clear() From 9bee671ed73b8a961918747475e9f25cfefbbedb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 13:35:33 -0700 Subject: [PATCH 093/167] Fixed bad transaction staleness bug --- go/libraries/doltcore/sqle/dsess/session.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 0ea1f8a7d3..8dc34341d3 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -317,12 +317,17 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra if err != nil { return nil, err } - + + // The engine sets the transaction after this call as well, but since we begin accessing data below, we need to set + // this now to avoid seeding the session state with stale data in some cases. The duplication is harmless since the + // code below cannot error, but it would to get rid of + ctx.SetTransaction(tx) + // Set session vars for every DB in this session using their current branch head for _, db := range doltDatabases { // faulty settings can make it impossible to load particular DB branch states, so we ignore any errors in this // loop and just decline to set the session vars. Throwing an error on transaction start in these cases makes it - // impossible for the user to correct any problems. + // impossible for the user to correct any problems. bs, ok, err := d.lookupDbState(ctx, db.Name()) if err != nil || !ok { continue @@ -331,7 +336,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra _ = d.setSessionVarsForDb(ctx, db.Name(), bs) } - return tx, err + return tx, nil } // clear clears all DB state for this session From c8235265f6b714b9226ea616cdf8b2c706ca9970 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 13:38:02 -0700 Subject: [PATCH 094/167] Re-skip test --- go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index c75916ddbf..b0d9cde43d 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1579,7 +1579,7 @@ func installTestCommitClock(tcc *testCommitClock) func() { // TestSingleTransactionScript is a convenience method for debugging a single transaction test. Unskip and set to the // desired test. func TestSingleTransactionScript(t *testing.T) { - // t.Skip() + t.Skip() tcc := &testCommitClock{} cleanup := installTestCommitClock(tcc) From 293e73a3bed931a75bec168c6829ce9d09a5275f Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 15:58:49 -0700 Subject: [PATCH 095/167] New gms --- go/go.mod | 2 +- go/go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go/go.mod b/go/go.mod index bb2722564b..67224e957f 100644 --- a/go/go.mod +++ b/go/go.mod @@ -59,7 +59,7 @@ require ( github.com/cespare/xxhash v1.1.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.15.1-0.20230523172851-5ecfc1bc2af0 + github.com/dolthub/go-mysql-server v0.15.1-0.20230524225625-84b9148f86fb github.com/dolthub/swiss v0.1.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/golang-lru/v2 v2.0.2 diff --git a/go/go.sum b/go/go.sum index 91b87a53cd..8aaf3f6ef2 100644 --- a/go/go.sum +++ b/go/go.sum @@ -170,6 +170,8 @@ github.com/dolthub/go-icu-regex v0.0.0-20230516121657-5424676dd4ac h1:/bsG4AyV5M github.com/dolthub/go-icu-regex v0.0.0-20230516121657-5424676dd4ac/go.mod h1:xLKpPutKiF9FxxcLG3gf/JA95YZQNAqBegkDRe1AZF4= github.com/dolthub/go-mysql-server v0.15.1-0.20230523172851-5ecfc1bc2af0 h1:UGMgP9QkOW3kk566+307dZSHAOyDk0jt/AEu1liWOfs= github.com/dolthub/go-mysql-server v0.15.1-0.20230523172851-5ecfc1bc2af0/go.mod h1:QtEmore89AqJ0j039nSXGKpOUbzx9+LRuwrnfd4sua8= +github.com/dolthub/go-mysql-server v0.15.1-0.20230524225625-84b9148f86fb h1:BOOSjL56La71386l0Ad8IKvkopj3Zz97nhrjWv5hUpo= +github.com/dolthub/go-mysql-server v0.15.1-0.20230524225625-84b9148f86fb/go.mod h1:y9ZGm0yf/UFfztugI31qSLAcvG/BfmkVoffu+uv/0MY= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto= github.com/dolthub/jsonpath v0.0.1 h1:Nd+T3U+XisK3kOuxtABS5IIbZqXVIlOR9VYquyjQ0u0= From 356e376fa6134c8dcec65d88b0e46f19acd9a4bb Mon Sep 17 00:00:00 2001 From: zachmu Date: Wed, 24 May 2023 23:09:03 +0000 Subject: [PATCH 096/167] [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh --- go/cmd/dolt/commands/sqlserver/server_test.go | 10 +++++----- go/go.sum | 2 -- .../doltcore/sqle/database_provider.go | 19 ++++++++++--------- go/libraries/doltcore/sqle/dsess/session.go | 12 ++++++------ .../dolt_transaction_commit_test.go | 2 +- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/go/cmd/dolt/commands/sqlserver/server_test.go b/go/cmd/dolt/commands/sqlserver/server_test.go index 429911d826..c88a5baf23 100644 --- a/go/cmd/dolt/commands/sqlserver/server_test.go +++ b/go/cmd/dolt/commands/sqlserver/server_test.go @@ -328,7 +328,7 @@ func TestServerSetDefaultBranch(t *testing.T) { require.NoError(t, err) sess := conn.NewSession(nil) - tests := []defaultBranchTest { + tests := []defaultBranchTest{ { query: sess.SelectBySql("select active_branch() as branch"), expectedRes: []testResult{{defaultBranch}}, @@ -349,7 +349,7 @@ func TestServerSetDefaultBranch(t *testing.T) { require.NoError(t, err) sess = conn.NewSession(nil) - tests = []defaultBranchTest { + tests = []defaultBranchTest{ { query: sess.SelectBySql("select active_branch() as branch"), expectedRes: []testResult{{defaultBranch}}, @@ -384,7 +384,7 @@ func TestServerSetDefaultBranch(t *testing.T) { expectedRes: nil, }, } - + runDefaultBranchTests(t, tests, conn) conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) @@ -399,7 +399,7 @@ func TestServerSetDefaultBranch(t *testing.T) { } runDefaultBranchTests(t, tests, conn) - + conn, err = dbr.Open("mysql", ConnectionString(serverConfig, dbName), nil) require.NoError(t, err) sess = conn.NewSession(nil) @@ -419,7 +419,7 @@ func TestServerSetDefaultBranch(t *testing.T) { tests = []defaultBranchTest{ { - query: sess.SelectBySql("select active_branch() as branch"), + query: sess.SelectBySql("select active_branch() as branch"), expectedErrStr: "database not found", // TODO: should be a better error message }, } diff --git a/go/go.sum b/go/go.sum index 8aaf3f6ef2..14cc4e38e5 100644 --- a/go/go.sum +++ b/go/go.sum @@ -168,8 +168,6 @@ 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-20230516121657-5424676dd4ac h1:/bsG4AyV5MesUPw7LSkxHKMsP9f+LSLrsMbBxLP6+Mk= github.com/dolthub/go-icu-regex v0.0.0-20230516121657-5424676dd4ac/go.mod h1:xLKpPutKiF9FxxcLG3gf/JA95YZQNAqBegkDRe1AZF4= -github.com/dolthub/go-mysql-server v0.15.1-0.20230523172851-5ecfc1bc2af0 h1:UGMgP9QkOW3kk566+307dZSHAOyDk0jt/AEu1liWOfs= -github.com/dolthub/go-mysql-server v0.15.1-0.20230523172851-5ecfc1bc2af0/go.mod h1:QtEmore89AqJ0j039nSXGKpOUbzx9+LRuwrnfd4sua8= github.com/dolthub/go-mysql-server v0.15.1-0.20230524225625-84b9148f86fb h1:BOOSjL56La71386l0Ad8IKvkopj3Zz97nhrjWv5hUpo= github.com/dolthub/go-mysql-server v0.15.1-0.20230524225625-84b9148f86fb/go.mod h1:y9ZGm0yf/UFfztugI31qSLAcvG/BfmkVoffu+uv/0MY= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 161283c71d..5200a8ca5b 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -21,6 +21,8 @@ import ( "strings" "sync" + "github.com/dolthub/go-mysql-server/sql" + "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/dolt/go/libraries/doltcore/dbfactory" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" @@ -35,7 +37,6 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/table/editor" "github.com/dolthub/dolt/go/libraries/utils/filesys" "github.com/dolthub/dolt/go/store/types" - "github.com/dolthub/go-mysql-server/sql" ) type DoltDatabaseProvider struct { @@ -733,7 +734,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual switch dbType { case dsess.RevisionTypeBranch: // fetch the upstream head if this is a replicated db - replicaDb, ok := srcDb.(ReadReplicaDatabase); + replicaDb, ok := srcDb.(ReadReplicaDatabase) if ok && replicaDb.ValidReplicaState(ctx) { // TODO move this out of analysis phase, should only happen at read time, when the transaction begins (like is // the case with a branch that already exists locally) @@ -1073,11 +1074,11 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds return nil, false, err } - // A newly created session may not have any info on current head stored yet, in which case we get the default - // branch for the db itself instead. + // A newly created session may not have any info on current head stored yet, in which case we get the default + // branch for the db itself instead. if !ok { usingDefaultBranch = true - + // First check the global variable for the default branch _, val, ok := sql.SystemVariables.GetGlobal(dsess.DefaultBranchKey(db.Name())) if ok { @@ -1089,8 +1090,8 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds head = "" // continue to below } - } - + } + // Fall back to the database's checked out branch if head == "" { rsr := db.DbData().Rsr @@ -1109,14 +1110,14 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds if err != nil { if sql.ErrDatabaseNotFound.Is(err) && usingDefaultBranch { // We can return a better error message here in some cases - // TODO: this better error message doesn't always get returned to clients because the code path is doesn't + // TODO: this better error message doesn't always get returned to clients because the code path is doesn't // return an error, only a boolean result (HasDB) return nil, false, fmt.Errorf("cannot resolve default branch head for database '%s': '%s'", baseName, head) } else { return nil, false, err } } - + if !ok { return nil, false, nil } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 8dc34341d3..8a114dcfdf 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -273,8 +273,8 @@ func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { // StartTransaction refreshes the state of this session and starts a new transaction. func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.TransactionCharacteristic) (sql.Transaction, error) { - // TODO: this is only necessary to support filter-branch, which needs to set a root directly and not have the - // session state altered when a transaction begins + // TODO: this is only necessary to support filter-branch, which needs to set a root directly and not have the + // session state altered when a transaction begins if TransactionsDisabled(ctx) { return DisabledTransaction{}, nil } @@ -318,14 +318,14 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra return nil, err } - // The engine sets the transaction after this call as well, but since we begin accessing data below, we need to set - // this now to avoid seeding the session state with stale data in some cases. The duplication is harmless since the + // The engine sets the transaction after this call as well, but since we begin accessing data below, we need to set + // this now to avoid seeding the session state with stale data in some cases. The duplication is harmless since the // code below cannot error, but it would to get rid of ctx.SetTransaction(tx) // Set session vars for every DB in this session using their current branch head for _, db := range doltDatabases { - // faulty settings can make it impossible to load particular DB branch states, so we ignore any errors in this + // faulty settings can make it impossible to load particular DB branch states, so we ignore any errors in this // loop and just decline to set the session vars. Throwing an error on transaction start in these cases makes it // impossible for the user to correct any problems. bs, ok, err := d.lookupDbState(ctx, db.Name()) @@ -335,7 +335,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra _ = d.setSessionVarsForDb(ctx, db.Name(), bs) } - + return tx, nil } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go index 327f839068..ae5970c4be 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_commit_test.go @@ -384,7 +384,7 @@ func TestDoltTransactionCommitAutocommit(t *testing.T) { if !ok { t.Fatal("'mydb' database not found") } - + headSpec, err := doltdb.NewCommitSpec("HEAD") require.NoError(t, err) headRefs, err := db.GetHeadRefs(context.Background()) From 7f8d926b0074e2924049a9ccb12c5fee2e6ac444 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 16:11:12 -0700 Subject: [PATCH 097/167] Fixed test --- go/cmd/dolt/commands/sqlserver/server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/dolt/commands/sqlserver/server_test.go b/go/cmd/dolt/commands/sqlserver/server_test.go index 429911d826..92e6354652 100644 --- a/go/cmd/dolt/commands/sqlserver/server_test.go +++ b/go/cmd/dolt/commands/sqlserver/server_test.go @@ -420,7 +420,7 @@ func TestServerSetDefaultBranch(t *testing.T) { tests = []defaultBranchTest{ { query: sess.SelectBySql("select active_branch() as branch"), - expectedErrStr: "database not found", // TODO: should be a better error message + expectedErrStr: "cannot resolve default branch head", // TODO: should be a better error message }, } From 974e313bd7507c284ea83cb0eeeae2d8e3b6a6a2 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 16:22:08 -0700 Subject: [PATCH 098/167] PR feedback --- go/libraries/doltcore/sqle/dsess/session.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 8a114dcfdf..6da41c8753 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -373,8 +373,9 @@ func (d *DoltSession) newWorkingSetForHead(ctx *sql.Context, wsRef ref.WorkingSe return doltdb.EmptyWorkingSet(wsRef).WithWorkingRoot(headRoot).WithStagedRoot(headRoot), nil } -// CommitTransaction commits the in-progress transaction for the database named. Depending on session settings, this -// may write only a new working set, or may additionally create a new dolt commit for the current HEAD. +// CommitTransaction commits the in-progress transaction. Depending on session settings, this may write only a new +// working set, or may additionally create a new dolt commit for the current HEAD. If more than one branch head has +// changes, the transaction is rejected. func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) error { if d.BatchMode() == Batched { for _, db := range d.provider.DoltDatabases() { From 49aaff49970b054676cc0bcea5c826659550b060 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 17:02:08 -0700 Subject: [PATCH 099/167] Databases now expose the name they were requested with, not their base name. --- go/libraries/doltcore/sqle/database.go | 15 ++++++++------- go/libraries/doltcore/sqle/dsess/session.go | 11 ++++------- go/libraries/doltcore/sqle/dsess/transactions.go | 1 + go/libraries/doltcore/sqle/dsess/variables.go | 2 ++ 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 05fc751373..4d8e922f33 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -116,12 +116,13 @@ func NewDatabase(ctx context.Context, name string, dbData env.DbData, editOpts e } return Database{ - name: name, - ddb: dbData.Ddb, - rsr: dbData.Rsr, - rsw: dbData.Rsw, - gs: globalState, - editOpts: editOpts, + name: name, + requestedName: name, + ddb: dbData.Ddb, + rsr: dbData.Rsr, + rsw: dbData.Rsw, + gs: globalState, + editOpts: editOpts, }, nil } @@ -141,7 +142,7 @@ func (db Database) InitialDBState(ctx *sql.Context, branch string) (dsess.Initia // Name returns the name of this database, set at creation time. func (db Database) Name() string { - return db.name + return db.RequestedName() } // RevisionQualifiedName returns the name of this database including its revision qualifier, if any. This method should diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 6da41c8753..6e325f5dd2 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -830,11 +830,6 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R // via setRoot. This method is for clients that need to update more of the session state, such as the dolt_ functions. // Unlike setting the working root, this method always marks the database state dirty. func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roots) error { - _, rev := SplitRevisionDbName(dbName) - if rev != "" { - return fmt.Errorf("cannot set roots for a revision database") - } - sessionState, _, err := d.LookupDbState(ctx, dbName) if err != nil { return err @@ -1091,7 +1086,9 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { DefineSystemVariablesForDB(db.Name()) - baseName, rev := db.Name(), db.Revision() + revisionQualifiedName := db.Name() + baseName, _ := SplitRevisionDbName(revisionQualifiedName) + // TODO: odd that we need to tell the DB what its own revision is here dbState, err := db.InitialDBState(ctx, db.Revision()) if err != nil { @@ -1120,7 +1117,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } branchState := NewEmptyBranchState(sessionState) - sessionState.heads[strings.ToLower(rev)] = branchState + sessionState.heads[strings.ToLower(db.Revision())] = branchState d.mu.Unlock() // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index cc79595061..0da9a9cfe4 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -128,6 +128,7 @@ func (tx DoltTransaction) IsReadOnly() bool { // GetInitialRoot returns the noms root hash for the db named, established when the transaction began. The dbName here // is always the base name of the database, not the revision qualified one. func (tx DoltTransaction) GetInitialRoot(dbName string) (hash.Hash, bool) { + dbName, _ = SplitRevisionDbName(dbName) startPoint, ok := tx.dbStartPoints[strings.ToLower(dbName)] return startPoint.rootHash, ok } diff --git a/go/libraries/doltcore/sqle/dsess/variables.go b/go/libraries/doltcore/sqle/dsess/variables.go index 07b18431e7..82baf1f5d5 100644 --- a/go/libraries/doltcore/sqle/dsess/variables.go +++ b/go/libraries/doltcore/sqle/dsess/variables.go @@ -61,6 +61,8 @@ const URLTemplateDatabasePlaceholder = "{database}" // DefineSystemVariablesForDB defines per database dolt-session variables in the engine as necessary func DefineSystemVariablesForDB(name string) { + name, _ = SplitRevisionDbName(name) + if _, _, ok := sql.SystemVariables.GetGlobal(name + HeadKeySuffix); !ok { sql.SystemVariables.AddSystemVariables([]sql.SystemVariable{ { From 91bb88946dc91ac9cdf93aa0ad3bcb9e9d4d0ba1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 24 May 2023 17:34:47 -0700 Subject: [PATCH 100/167] Test fixes --- .../doltcore/sqle/dprocedures/dolt_branch.go | 12 +++++++----- .../sqle/enginetest/dolt_engine_test.go | 2 +- .../doltcore/sqle/enginetest/dolt_queries.go | 8 ++++---- .../sqle/enginetest/dolt_server_test.go | 17 +++++++---------- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go index 3669788fcc..865bb0a02b 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go @@ -222,10 +222,11 @@ func shouldAllowDefaultBranchDeletion(ctx *sql.Context) bool { // selected as the active branch for any active server sessions. func validateBranchNotActiveInAnySession(ctx *sql.Context, branchName string) error { currentDbName := ctx.GetCurrentDatabase() + currentDbName, _ = dsess.SplitRevisionDbName(currentDbName) if currentDbName == "" { return nil } - + if sqlserver.RunningInServerMode() == false { return nil } @@ -238,17 +239,18 @@ func validateBranchNotActiveInAnySession(ctx *sql.Context, branchName string) er branchRef := ref.NewBranchRef(branchName) return sessionManager.Iter(func(session sql.Session) (bool, error) { - dsess, ok := session.(*dsess.DoltSession) + sess, ok := session.(*dsess.DoltSession) if !ok { return false, fmt.Errorf("unexpected session type: %T", session) } - sessionDbName := dsess.Session.GetCurrentDatabase() - if len(sessionDbName) == 0 || sessionDbName != currentDbName { + sessionDbName := sess.Session.GetCurrentDatabase() + baseName, _ := dsess.SplitRevisionDbName(sessionDbName) + if len(baseName) == 0 || baseName != currentDbName { return false, nil } - activeBranchRef, err := dsess.CWBHeadRef(ctx, sessionDbName) + activeBranchRef, err := sess.CWBHeadRef(ctx, sessionDbName) if err != nil { // The above will throw an error if the current DB doesn't have a head ref, in which case we don't need to // consider it diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index b0d9cde43d..a412b7dede 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1226,7 +1226,7 @@ func TestDoltRevisionDbScripts(t *testing.T) { }, { Query: "select database();", - Expected: []sql.Row{{"mydb"}}, + Expected: []sql.Row{{"use mydb/" + commithash}}, }, { Query: "show databases;", diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 8c85d71c76..f8a059432c 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -313,7 +313,7 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ { // The database name is always the base name, never the revision specifier Query: "select database()", - Expected: []sql.Row{{"mydb"}}, + Expected: []sql.Row{{"mydb/tag1~"}}, }, { // The branch is nil in the case of a non-branch revision DB @@ -391,7 +391,7 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ { // The database name is always the base name, never the revision specifier Query: "select database()", - Expected: []sql.Row{{"mydb"}}, + Expected: []sql.Row{{"mydb/tag1"}}, }, { // The branch is nil in the case of a non-branch revision DB @@ -460,7 +460,7 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ { // The database name is always the base name, never the revision specifier Query: "select database()", - Expected: []sql.Row{{"mydb"}}, + Expected: []sql.Row{{"mydb/branch1"}}, }, { Query: "select active_branch()", @@ -492,7 +492,7 @@ var DoltRevisionDbScripts = []queries.ScriptTest{ }, { Query: "select database();", - Expected: []sql.Row{{"mydb"}}, + Expected: []sql.Row{{"mydb/branch1"}}, }, { Query: "show databases;", diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index 7ac99ec575..7f2031c363 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -121,7 +121,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt", "branch1"}}, + Expected: []sql.Row{{"dolt/branch1", "branch1"}}, }, { Query: "/* client b */ use dolt/branch2;", @@ -129,7 +129,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client b */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt", "branch2"}}, + Expected: []sql.Row{{"dolt/branch2", "branch2"}}, }, { Query: "/* client a */ SHOW DATABASES;", @@ -168,7 +168,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt", "branch1"}}, + Expected: []sql.Row{{"dolt/branch1", "branch1"}}, }, { Query: "/* client b */ use dolt/branch2;", @@ -176,7 +176,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client b */ SELECT DATABASE(), ACTIVE_BRANCH();", - Expected: []sql.Row{{"dolt", "branch2"}}, + Expected: []sql.Row{{"dolt/branch2", "branch2"}}, }, { Query: "/* client a */ SHOW DATABASES;", @@ -406,14 +406,11 @@ var DropDatabaseMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client b */ select database();", - Expected: []sql.Row{{"db01"}}, + Expected: []sql.Row{{"db01/branch1"}}, }, - // TODO: this could be better: there's no longer a branch branch1, and we lose track of the fact that we were on - // branch1 when the `drop database` is processed -- as far as the engine is concerned we are using a database - // called `db01`, no branch info. It's enough for now to not panic in this edge case. { Query: "/* client b */ show tables;", - Expected: []sql.Row{}, + ExpectedErrStr: "Error 1105: database not found: db01/branch1", }, }, }, @@ -464,7 +461,7 @@ func testMultiSessionScriptTests(t *testing.T, tests []queries.ScriptTest) { if len(assertion.ExpectedErrStr) > 0 { require.EqualError(t, err, assertion.ExpectedErrStr) } else if assertion.ExpectedErr != nil { - require.True(t, assertion.ExpectedErr.Is(err)) + require.True(t, assertion.ExpectedErr.Is(err), "expected error %v, got %v", assertion.ExpectedErr, err) } else if assertion.Expected != nil { require.NoError(t, err) assertResultsEqual(t, assertion.Expected, rows) From c9eaf99ec283198390ebe363a4dafd67cd8a9f54 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 25 May 2023 13:32:16 -0700 Subject: [PATCH 101/167] dolt_checkout changes the current db to the base name --- go/libraries/doltcore/sqle/dsess/session.go | 4 +++- go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 6e325f5dd2..1520e2a9a4 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -935,7 +935,9 @@ func (d *DoltSession) SwitchWorkingSet( if !ok { return sql.ErrDatabaseNotFound.New(dbName) } - + + ctx.SetCurrentDatabase(baseName) + return nil } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index a412b7dede..fbf8c1b4fc 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1226,7 +1226,7 @@ func TestDoltRevisionDbScripts(t *testing.T) { }, { Query: "select database();", - Expected: []sql.Row{{"use mydb/" + commithash}}, + Expected: []sql.Row{{"mydb/" + commithash}}, }, { Query: "show databases;", From ebfba2d424d3f94f38d0817487935057c8564e48 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 26 May 2023 15:11:46 -0700 Subject: [PATCH 102/167] bug fix for checking out a new branch --- .../sqle/dprocedures/dolt_checkout.go | 2 +- go/libraries/doltcore/sqle/dsess/session.go | 24 --- .../sqle/enginetest/dolt_engine_test.go | 44 ++++-- .../sqle/enginetest/dolt_queries_merge.go | 141 ++++++++++++++++++ 4 files changed, 172 insertions(+), 39 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go index 0fb5f1f6ce..1863a5e933 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_checkout.go @@ -272,7 +272,7 @@ func checkoutNewBranch(ctx *sql.Context, dbName string, dbData env.DbData, apr * return err } - return sess.SetCurrentHead(ctx, dbName, wsRef) + return sess.SwitchWorkingSet(ctx, dbName, wsRef) } func checkoutBranch(ctx *sql.Context, dbName string, branchName string) error { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 1520e2a9a4..641e364bb6 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -873,30 +873,6 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. return nil } -// SetCurrentHead sets the currently connected head revision spec for this session. This changes the revision that -// unqualified references to the database name resolve to, and is only done by dolt_checkout(). -func (d *DoltSession) SetCurrentHead(ctx *sql.Context, dbName string, wsRef ref.WorkingSetRef) error { - headRef, err := wsRef.ToHeadRef() - if err != nil { - return err - } - - d.mu.Lock() - defer d.mu.Unlock() - - baseName, _ := SplitRevisionDbName(dbName) - dbState, ok := d.dbStates[strings.ToLower(baseName)] - if !ok { - return sql.ErrDatabaseNotFound.New(dbName) - } - - dbState.checkedOutRevSpec = headRef.GetPath() - dbState.currRevSpec = headRef.GetPath() - dbState.currRevType = RevisionTypeBranch - - return nil -} - // SwitchWorkingSet switches to a new working set for this session. Unlike SetWorkingSet, this method expresses no // intention to eventually persist any uncommitted changes. Rather, this method only changes the in memory state of // this session. It's equivalent to starting a new session with the working set reference provided. If the current diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index fbf8c1b4fc..ea6be5917c 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -115,22 +115,21 @@ func TestSingleQuery(t *testing.T) { // Convenience test for debugging a single query. Unskip and set to the desired query. func TestSingleScript(t *testing.T) { - t.Skip() + // t.Skip() - var script = queries.ScriptTest{ - Name: "CALL DOLT_MERGE ff correctly works with autocommit off", + var script = queries.ScriptTest { + Name: "CALL DOLT_MERGE ff no checkout", SetUpScript: []string{ "CREATE TABLE test (pk int primary key)", - "call DOLT_ADD('.')", + "CALL DOLT_ADD('.')", "INSERT INTO test VALUES (0),(1),(2);", - "SET autocommit = 0", "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", - "CALL DOLT_CHECKOUT('-b', 'feature-branch')", + "CALL dolt_branch('feature-branch')", + "use `mydb/feature-branch`", "INSERT INTO test VALUES (3);", "UPDATE test SET pk=1000 WHERE pk=0;", - "CALL DOLT_ADD('.');", "CALL DOLT_COMMIT('-a', '-m', 'this is a ff');", - "CALL DOLT_CHECKOUT('main');", + "use mydb/main;", }, Assertions: []queries.ScriptTestAssertion{ { @@ -142,10 +141,6 @@ func TestSingleScript(t *testing.T) { Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", Expected: []sql.Row{{false, nil, nil, nil}}, }, - { - Query: "SELECT * from dolt_diff_test where to_commit = 'WORKING'", - Expected: []sql.Row{}, - }, { Query: "SELECT * from dolt_status", Expected: []sql.Row{}, @@ -154,14 +149,34 @@ func TestSingleScript(t *testing.T) { Query: "CALL DOLT_CHECKOUT('-b', 'new-branch')", Expected: []sql.Row{{0}}, }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"new-branch"}}, + }, { Query: "INSERT INTO test VALUES (4)", Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, }, + { + Query: "SELECT * FROM test order by pk", + Expected: []sql.Row{{1}, {2}, {3}, {4}, {1000}}, + }, + { + Query: "use `mydb/main`", + SkipResultsCheck: true, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "SELECT * FROM test order by pk", + Expected: []sql.Row{{1}, {2}, {3}, {1000}}, + }, }, } - tcc := &testCommitClock{} + tcc := &testCommitClock{} cleanup := installTestCommitClock(tcc) defer cleanup() @@ -1356,7 +1371,8 @@ func TestViewsWithAsOfPrepared(t *testing.T) { func TestDoltMerge(t *testing.T) { for _, script := range MergeScripts { - // dolt versioning conflicts with reset harness -- use new harness every time + // harness can't reset effectively when there are new commits / branches created, so use a new harness for + // each script func() { h := newDoltHarness(t).WithParallelism(1) defer h.Close() diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index f202e6ef36..5ad608db6d 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -89,6 +89,44 @@ var MergeScripts = []queries.ScriptTest{ }, }, }, + { + Name: "CALL DOLT_MERGE ff correctly works with autocommit off, no checkout", + SetUpScript: []string{ + "CREATE TABLE test (pk int primary key)", + "call DOLT_ADD('.')", + "INSERT INTO test VALUES (0),(1),(2);", + "SET autocommit = 0", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", + "CALL DOLT_BRANCH('feature-branch')", + "use `mydb/feature-branch`", + "INSERT INTO test VALUES (3);", + "UPDATE test SET pk=1000 WHERE pk=0;", + "CALL DOLT_ADD('.');", + "CALL DOLT_COMMIT('-a', '-m', 'this is a ff');", + "use mydb/main;", + }, + Assertions: []queries.ScriptTestAssertion{ + { + // FF-Merge + Query: "CALL DOLT_MERGE('feature-branch')", + Expected: []sql.Row{{1, 0}}, + }, + { + Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", + Expected: []sql.Row{{false, nil, nil, nil}}, + }, + { + Query: "SELECT * from dolt_status", + Expected: []sql.Row{}, + }, + { + Query: "select * from test order by 1", + Expected: []sql.Row{ + {1}, {2}, {3}, {1000}, + }, + }, + }, + }, { Name: "CALL DOLT_MERGE no-ff correctly works with autocommit off", SetUpScript: []string{ @@ -131,6 +169,51 @@ var MergeScripts = []queries.ScriptTest{ }, }, }, + { + Name: "CALL DOLT_MERGE no-ff correctly works with autocommit off, no checkout", + SetUpScript: []string{ + "CREATE TABLE test (pk int primary key)", + "call DOLT_ADD('.')", + "INSERT INTO test VALUES (0),(1),(2);", + "SET autocommit = 0", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1', '--date', '2022-08-06T12:00:00');", + "CALL DOLT_BRANCH('feature-branch')", + "USE `mydb/feature-branch`", + "INSERT INTO test VALUES (3);", + "UPDATE test SET pk=1000 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'this is a ff', '--date', '2022-08-06T12:00:01');", + "use `mydb/main`", + }, + Assertions: []queries.ScriptTestAssertion{ + { + // No-FF-Merge + Query: "CALL DOLT_MERGE('feature-branch', '-no-ff', '-m', 'this is a no-ff')", + Expected: []sql.Row{{1, 0}}, + }, + { + Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", + Expected: []sql.Row{{false, nil, nil, nil}}, + }, + { + Query: "SELECT * from dolt_status", + Expected: []sql.Row{}, + }, + { + Query: "SELECT COUNT(*) FROM dolt_log", + Expected: []sql.Row{{5}}, // includes the merge commit created by no-ff and setup commits + }, + { + Query: "select message from dolt_log order by date DESC LIMIT 1;", + Expected: []sql.Row{{"this is a no-ff"}}, // includes the merge commit created by no-ff + }, + { + Query: "select * from test order by 1", + Expected: []sql.Row{ + {1}, {2}, {3}, {1000}, + }, + }, + }, + }, { Name: "CALL DOLT_MERGE without conflicts correctly works with autocommit off with commit flag", SetUpScript: []string{ @@ -408,6 +491,64 @@ var MergeScripts = []queries.ScriptTest{ }, }, }, + { + Name: "CALL DOLT_MERGE ff no checkout", + SetUpScript: []string{ + "CREATE TABLE test (pk int primary key)", + "CALL DOLT_ADD('.')", + "INSERT INTO test VALUES (0),(1),(2);", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", + "CALL dolt_branch('feature-branch')", + "use `mydb/feature-branch`", + "INSERT INTO test VALUES (3);", + "UPDATE test SET pk=1000 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'this is a ff');", + "use mydb/main;", + }, + Assertions: []queries.ScriptTestAssertion{ + { + // FF-Merge + Query: "CALL DOLT_MERGE('feature-branch')", + Expected: []sql.Row{{1, 0}}, + }, + { + Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", + Expected: []sql.Row{{false, nil, nil, nil}}, + }, + { + Query: "SELECT * from dolt_status", + Expected: []sql.Row{}, + }, + { + Query: "CALL DOLT_CHECKOUT('-b', 'new-branch')", + Expected: []sql.Row{{0}}, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"new-branch"}}, + }, + { + Query: "INSERT INTO test VALUES (4)", + Expected: []sql.Row{{types.NewOkResult(1)}}, + }, + { + Query: "SELECT * FROM test order by pk", + Expected: []sql.Row{{1}, {2}, {3}, {4}, {1000}}, + }, + { + Query: "use `mydb/main`", + SkipResultsCheck: true, + }, + { + Query: "select active_branch()", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "SELECT * FROM test order by pk", + Expected: []sql.Row{{1}, {2}, {3}, {1000}}, + }, + }, + }, { Name: "CALL DOLT_MERGE no-ff", SetUpScript: []string{ From 1beca1ffb491f2a2d61b7b715da2fc1f68a73641 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 26 May 2023 15:50:01 -0700 Subject: [PATCH 103/167] More tests of merge --- .../sqle/enginetest/dolt_engine_test.go | 22 ++++++++ .../sqle/enginetest/dolt_queries_merge.go | 55 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index ea6be5917c..f90cc717d8 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1391,6 +1391,28 @@ func TestDoltMerge(t *testing.T) { } } +func TestDoltMergePrepared(t *testing.T) { + for _, script := range MergeScripts { + // harness can't reset effectively when there are new commits / branches created, so use a new harness for + // each script + func() { + h := newDoltHarness(t).WithParallelism(1) + defer h.Close() + enginetest.TestScriptPrepared(t, h, script) + }() + } + + if types.IsFormat_DOLT(types.Format_Default) { + for _, script := range Dolt1MergeScripts { + func() { + h := newDoltHarness(t).WithParallelism(1) + defer h.Close() + enginetest.TestScriptPrepared(t, h, script) + }() + } + } +} + func TestDoltAutoIncrement(t *testing.T) { for _, script := range DoltAutoIncrementTests { // doing commits on different branches is antagonistic to engine reuse, use a new engine on each script diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index 5ad608db6d..f5da745b01 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -628,6 +628,61 @@ var MergeScripts = []queries.ScriptTest{ }, }, }, + { + Name: "CALL DOLT_MERGE with no conflicts works, no checkout", + SetUpScript: []string{ + "CREATE TABLE test (pk int primary key)", + "CALL DOLT_ADD('.')", + "INSERT INTO test VALUES (0),(1),(2);", + "CALL DOLT_COMMIT('-a', '-m', 'Step 1', '--date', '2022-08-06T12:00:00');", + "CALL dolt_branch('feature-branch')", + "use `mydb/feature-branch`", + "INSERT INTO test VALUES (3);", + "UPDATE test SET pk=1000 WHERE pk=0;", + "CALL DOLT_COMMIT('-a', '-m', 'this is a normal commit', '--date', '2022-08-06T12:00:01');", + "use mydb/main", + "INSERT INTO test VALUES (5),(6),(7);", + "CALL DOLT_COMMIT('-a', '-m', 'add some more values', '--date', '2022-08-06T12:00:02');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "CALL DOLT_MERGE('feature-branch', '--no-commit', '--commit')", + ExpectedErrStr: "cannot define both 'commit' and 'no-commit' flags at the same time", + }, + { + Query: "CALL DOLT_MERGE('feature-branch', '-m', 'this is a merge')", + Expected: []sql.Row{{0, 0}}, + }, + { + Query: "SELECT COUNT(*) from dolt_status", + Expected: []sql.Row{{0}}, + }, + { + Query: "SELECT COUNT(*) FROM dolt_log", + Expected: []sql.Row{{6}}, // includes the merge commit and a new commit created by successful merge + }, + { + Query: "select message from dolt_log where date > '2022-08-08' order by date DESC LIMIT 1;", + Expected: []sql.Row{{"this is a merge"}}, + }, + { + Query: "select * from test order by pk", + Expected: []sql.Row{ + {1}, {2}, {3}, {5}, {6}, {7}, {1000}, + }, + }, + { + Query: "use `mydb/feature-branch`", + SkipResultsCheck: true, + }, + { + Query: "select * from test order by pk", + Expected: []sql.Row{ + {1}, {2}, {3}, {1000}, + }, + }, + }, + }, { Name: "CALL DOLT_MERGE with no conflicts works with no-commit flag", SetUpScript: []string{ From 3a77f7ba581953b60860ba0b233511c36333ded0 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 26 May 2023 16:12:39 -0700 Subject: [PATCH 104/167] More tests --- .../sqle/enginetest/dolt_queries_merge.go | 34 ++++++++++++ .../enginetest/dolt_transaction_queries.go | 53 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index f5da745b01..30eb5cce0e 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -1440,6 +1440,40 @@ var Dolt1MergeScripts = []queries.ScriptTest{ }, }, }, + { + Name: "dropping constraint from one branch drops from both, no checkout", + SetUpScript: []string{ + "create table t (i int)", + "alter table t add constraint c check (i > 0)", + "call dolt_commit('-Am', 'initial commit')", + + "call dolt_branch('other')", + "use mydb/other", + "insert into t values (1)", + "alter table t drop constraint c", + "call dolt_commit('-Am', 'changes to other')", + + "use mydb/main", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into t values (-1)", + ExpectedErr: sql.ErrCheckConstraintViolated, + }, + { + Query: "CALL DOLT_MERGE('other');", + Expected: []sql.Row{{1, 0}}, + }, + { + Query: "select * from t", + Expected: []sql.Row{{1}}, + }, + { + Query: "insert into t values (-1)", + Expected: []sql.Row{{types.NewOkResult(1)}}, + }, + }, + }, { Name: "merge constraint with valid data on different branches", SetUpScript: []string{ diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 2b7cf64a4f..865f1f2c1c 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2380,6 +2380,59 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to another branch with dolt_transaction_commit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = 0", + "set dolt_transaction_commit = on", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `mydb/b1`.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "insert into `mydb/b1`.t1 values (2)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "select * from `mydb/b1`.t1 order by a", + Expected: []sql.Row{ + {1}, {2}, + }, + }, + { + Query: "commit", + Expected: []sql.Row{}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{ + {1}, {2}, + }, + }, + }, + }, { Name: "committing to another branch with autocommit", SetUpScript: []string{ From 5e8dc91c606fbceeb160bfcd318428fd1f2be573 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 26 May 2023 16:41:39 -0700 Subject: [PATCH 105/167] Put guardrails on dolt_commit: dirty branch must be the one checked out --- go/libraries/doltcore/sqle/dsess/session.go | 32 +++++++++++++++++++ .../enginetest/dolt_transaction_queries.go | 10 +++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 641e364bb6..9b603577af 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -411,6 +411,12 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er dirtyBranchState := dirties[0] if peformDoltCommitInt == 1 { + // if the dirty working set doesn't belong to the currently checked out branch, that's an error + err2 := d.validateDoltCommit(ctx, dirtyBranchState) + if err2 != nil { + return err2 + } + pendingCommit, err := d.PendingCommitAllStaged(ctx, dirtyBranchState, actions.CommitStagedProps{ Message: "Transaction commit", Date: ctx.QueryTime(), @@ -435,6 +441,32 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er } } +func (d *DoltSession) validateDoltCommit(ctx *sql.Context, dirtyBranchState *branchState) error { + currDb := ctx.GetCurrentDatabase() + if currDb == "" { + return fmt.Errorf("cannot dolt_commit with no database selected") + } + baseName, _ := SplitRevisionDbName(currDb) + + d.mu.Lock() + dbState, ok := d.dbStates[strings.ToLower(baseName)] + d.mu.Unlock() + + if !ok { + return fmt.Errorf("no database state found for %s", baseName) + } + + dirtyBranch, err := dirtyBranchState.workingSet.Ref().ToHeadRef() + if err != nil { + return err + } + if dbState.currRevSpec != dirtyBranch.GetPath() { + return fmt.Errorf("no changes to dolt_commit on branch %s", dbState.currRevSpec) + } + + return nil +} + var ErrDirtyWorkingSets = errors.New("Cannot commit changes on more than one branch / database") // dirtyWorkingSets returns all dirty working sets for this session diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 865f1f2c1c..bac4e82eeb 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2415,16 +2415,16 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, { Query: "commit", + ExpectedErrStr: "no changes to dolt_commit on branch main", + }, + { + Query: "use mydb/b1", Expected: []sql.Row{}, }, { - Query: "select * from t1 order by a", + Query: "commit", Expected: []sql.Row{}, }, - { - Query: "call dolt_checkout('b1')", - SkipResultsCheck: true, - }, { Query: "select * from t1 order by a", Expected: []sql.Row{ From 4dd856993be46f0d2ecba89f7cb61b2e673de69c Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 26 May 2023 16:51:04 -0700 Subject: [PATCH 106/167] More tests --- .../enginetest/dolt_transaction_queries.go | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index bac4e82eeb..c92cae1ae7 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2465,6 +2465,43 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to another branch with autocommit and dolt_transaction_commit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = on", // unnecessary but make it explicit + "set dolt_transaction_commit = on", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `mydb/b1`.t1 values (1)", + ExpectedErrStr: "no changes to dolt_commit on branch main", + }, + { + Query: "use mydb/b1", + Expected: []sql.Row{}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{ + {1}, + }, + }, + { + Query: "commit", + Expected: []sql.Row{}, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{ + {1}, + }, + }, + }, + }, { Name: "checkout and use different branch", SetUpScript: []string{ From 27c8cdc4d39d899cb9be91c60bc58fdc78d5dfbc Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 30 May 2023 11:20:29 -0700 Subject: [PATCH 107/167] Bug fix: dolt_commit on another DB errors --- go/libraries/doltcore/sqle/dsess/session.go | 11 +++- .../enginetest/dolt_transaction_queries.go | 56 +++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 9b603577af..e74c107c0b 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -446,14 +446,19 @@ func (d *DoltSession) validateDoltCommit(ctx *sql.Context, dirtyBranchState *bra if currDb == "" { return fmt.Errorf("cannot dolt_commit with no database selected") } - baseName, _ := SplitRevisionDbName(currDb) + currDbBaseName, _ := SplitRevisionDbName(currDb) + dirtyDbBaseName, _ := SplitRevisionDbName(dirtyBranchState.dbState.dbName) + + if strings.ToLower(currDbBaseName) != strings.ToLower(dirtyDbBaseName) { + return fmt.Errorf("no changes to dolt_commit on database %s", currDbBaseName) + } d.mu.Lock() - dbState, ok := d.dbStates[strings.ToLower(baseName)] + dbState, ok := d.dbStates[strings.ToLower(currDbBaseName)] d.mu.Unlock() if !ok { - return fmt.Errorf("no database state found for %s", baseName) + return fmt.Errorf("no database state found for %s", currDbBaseName) } dirtyBranch, err := dirtyBranchState.workingSet.Ref().ToHeadRef() diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index c92cae1ae7..47df2c3bbf 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2699,6 +2699,62 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to another branch on another database with dolt_transaction_commit and autocommit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "create database db1", + "use db1", + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "commit", + "use mydb/b1", + "set autocommit = 1", + "set dolt_transaction_commit = 1", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `db1/b1`.t1 values (1)", + ExpectedErrStr: "no changes to dolt_commit on database mydb", + }, + }, + }, + { + Name: "committing to another branch on another database with dolt_transaction_commit, no autocommit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "create database db1", + "use db1", + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "commit", + "use mydb/b1", + "set autocommit = off", + "set dolt_transaction_commit = 1", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `db1/b1`.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "commit", + ExpectedErrStr: "no changes to dolt_commit on database mydb", + }, + }, + }, { Name: "committing to more than one branch at a time", SetUpScript: []string{ From c6210bc94246878ea2cab515cfaea44eefceaf41 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 30 May 2023 11:57:20 -0700 Subject: [PATCH 108/167] More multi-db / multi-branch tests, some reorg --- .../doltcore/sqle/dprocedures/dolt_branch.go | 1 + .../sqle/enginetest/dolt_engine_test.go | 69 ++++--------- .../enginetest/dolt_transaction_queries.go | 98 +++++++++++++++++-- 3 files changed, 109 insertions(+), 59 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go index 865bb0a02b..42582b5243 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go @@ -97,6 +97,7 @@ func commitTransaction(ctx *sql.Context, dSess *dsess.DoltSession, rsc *doltdb.R // Because this transaction manipulation is happening outside the engine's awareness, we need to set it to nil here // to get a fresh transaction started on the next statement. // TODO: put this under engine control + // TODO: move this into dsess.CommitTransaction? ctx.SetTransaction(nil) return nil } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index f90cc717d8..6b0c09fe82 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -118,65 +118,32 @@ func TestSingleScript(t *testing.T) { // t.Skip() var script = queries.ScriptTest { - Name: "CALL DOLT_MERGE ff no checkout", + Name: "committing to another branch on another database with dolt_transaction_commit", SetUpScript: []string{ - "CREATE TABLE test (pk int primary key)", - "CALL DOLT_ADD('.')", - "INSERT INTO test VALUES (0),(1),(2);", - "CALL DOLT_COMMIT('-a', '-m', 'Step 1');", - "CALL dolt_branch('feature-branch')", - "use `mydb/feature-branch`", - "INSERT INTO test VALUES (3);", - "UPDATE test SET pk=1000 WHERE pk=0;", - "CALL DOLT_COMMIT('-a', '-m', 'this is a ff');", - "use mydb/main;", + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "create database db1", + "use db1", + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "commit", + "use mydb/b1", + "set autocommit = 1", + "set dolt_transaction_commit = 1", }, Assertions: []queries.ScriptTestAssertion{ { - // FF-Merge - Query: "CALL DOLT_MERGE('feature-branch')", - Expected: []sql.Row{{1, 0}}, - }, - { - Query: "SELECT is_merging, source, target, unmerged_tables FROM DOLT_MERGE_STATUS;", - Expected: []sql.Row{{false, nil, nil, nil}}, - }, - { - Query: "SELECT * from dolt_status", - Expected: []sql.Row{}, - }, - { - Query: "CALL DOLT_CHECKOUT('-b', 'new-branch')", - Expected: []sql.Row{{0}}, - }, - { - Query: "select active_branch()", - Expected: []sql.Row{{"new-branch"}}, - }, - { - Query: "INSERT INTO test VALUES (4)", - Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, - }, - { - Query: "SELECT * FROM test order by pk", - Expected: []sql.Row{{1}, {2}, {3}, {4}, {1000}}, - }, - { - Query: "use `mydb/main`", - SkipResultsCheck: true, - }, - { - Query: "select active_branch()", - Expected: []sql.Row{{"main"}}, - }, - { - Query: "SELECT * FROM test order by pk", - Expected: []sql.Row{{1}, {2}, {3}, {1000}}, + Query: "insert into `db1/b1`.t1 values (1)", + ExpectedErrStr: "no changes to dolt_commit on database mydb", }, }, } - tcc := &testCommitClock{} + tcc := &testCommitClock{} cleanup := installTestCommitClock(tcc) defer cleanup() diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 47df2c3bbf..84da6aff04 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2380,6 +2380,36 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to another branch with autocommit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "set autocommit = on", // unnecessary but make it explicit + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `mydb/b1`.t1 values (1)", + Expected: []sql.Row{ + {types.OkResult{RowsAffected: 1}}, + }, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{{1}}, + }, + }, + }, { Name: "committing to another branch with dolt_transaction_commit", SetUpScript: []string{ @@ -2434,13 +2464,13 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Name: "committing to another branch with autocommit", + Name: "committing to another branch with dolt_commit", SetUpScript: []string{ "create table t1 (a int)", "call dolt_add('.')", "call dolt_commit('-am', 'new table')", "call dolt_branch('b1')", - "set autocommit = on", // unnecessary but make it explicit + "set autocommit = off", }, Assertions: []queries.ScriptTestAssertion{ { @@ -2454,14 +2484,24 @@ var MultiDbTransactionTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "call dolt_checkout('b1')", + Query: "call dolt_commit('-am', 'changes on b1')", + ExpectedErrStr: "nothing to commit", // this error is different from what you get with @@dolt_transaction_commit + }, + { + Query: "use mydb/b1", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_commit('-am', 'other changes on b1')", SkipResultsCheck: true, }, { Query: "select * from t1 order by a", - Expected: []sql.Row{ - {1}, - }, + Expected: []sql.Row{{1}}, + }, + { + Query: "select message from dolt_log order by date desc limit 1", + Expected: []sql.Row{{"other changes on b1"}}, }, }, }, @@ -2503,7 +2543,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Name: "checkout and use different branch", + Name: "active_branch with dolt_checkout and use", SetUpScript: []string{ "create table t1 (a int)", "call dolt_add('.')", @@ -2641,6 +2681,49 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, + { + Name: "committing to another database with dolt_commit", + SetUpScript: []string{ + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "create database db1", + "use db1", + "create table t1 (a int)", + "call dolt_add('.')", + "call dolt_commit('-am', 'new table')", + "call dolt_branch('b1')", + "use mydb/b1", + "set autocommit = off", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "insert into `db1/b1`.t1 values (1)", + Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, + }, + { + Query: "call dolt_commit('-am', 'changes on b1')", + ExpectedErrStr: "nothing to commit", // this error is different from what you get with @@dolt_transaction_commit + }, + { + Query: "use db1/b1", + Expected: []sql.Row{}, + }, + { + Query: "call dolt_commit('-am', 'other changes on b1')", + SkipResultsCheck: true, + }, + { + Query: "select * from t1 order by a", + Expected: []sql.Row{{1}}, + }, + { + Query: "select message from dolt_log order by date desc limit 1", + Expected: []sql.Row{{"other changes on b1"}}, + }, + }, + }, { Name: "committing to another branch on another database", SetUpScript: []string{ @@ -2712,7 +2795,6 @@ var MultiDbTransactionTests = []queries.ScriptTest{ "call dolt_add('.')", "call dolt_commit('-am', 'new table')", "call dolt_branch('b1')", - "commit", "use mydb/b1", "set autocommit = 1", "set dolt_transaction_commit = 1", From c380ecfada402a54703bbe8ebb25d59ca0c527b0 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 30 May 2023 12:24:57 -0700 Subject: [PATCH 109/167] Cleaned up and consolidated explicit tx management code to happen just in the session --- .../doltcore/sqle/dprocedures/dolt_branch.go | 7 +--- .../doltcore/sqle/dprocedures/dolt_merge.go | 9 ----- go/libraries/doltcore/sqle/dsess/session.go | 35 ++++++++++++------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go index 42582b5243..fefd359aea 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go @@ -93,12 +93,7 @@ func commitTransaction(ctx *sql.Context, dSess *dsess.DoltSession, rsc *doltdb.R if rsc != nil { dsess.WaitForReplicationController(ctx, *rsc) } - - // Because this transaction manipulation is happening outside the engine's awareness, we need to set it to nil here - // to get a fresh transaction started on the next statement. - // TODO: put this under engine control - // TODO: move this into dsess.CommitTransaction? - ctx.SetTransaction(nil) + return nil } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go index de1ec43901..a587de2328 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go @@ -106,9 +106,6 @@ func doDoltMerge(ctx *sql.Context, args []string) (int, int, error) { return noConflictsOrViolations, threeWayMerge, err } - // Because this commit happens outside the engine's control, we need to manually clear the transaction - ctx.SetTransaction(nil) - return noConflictsOrViolations, threeWayMerge, nil } @@ -301,9 +298,6 @@ func executeFFMerge(ctx *sql.Context, dbName string, squash bool, ws *doltdb.Wor if err != nil { return ws, err } - - // because this commit happens outside the SQL engine's awareness, we need to manually clear the transaction - ctx.SetTransaction(nil) } return ws, nil @@ -360,9 +354,6 @@ func executeNoFFMerge( return nil, err } - // because this commit happens outside the SQL engine's awareness, we need to manually clear the transaction - ctx.SetTransaction(nil) - return ws, nil } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index e74c107c0b..b70d2d8dc3 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -376,7 +376,17 @@ func (d *DoltSession) newWorkingSetForHead(ctx *sql.Context, wsRef ref.WorkingSe // CommitTransaction commits the in-progress transaction. Depending on session settings, this may write only a new // working set, or may additionally create a new dolt commit for the current HEAD. If more than one branch head has // changes, the transaction is rejected. -func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) error { +func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) (err error) { + // Any non-error path must set the ctx's transaction to nil even if no work was done, because the engine only clears + // out transaction state in some cases. Changes to only branch heads (creating a new branch, reset, etc.) have no + // changes to commit visible to the transaction logic, but they still need a new transaction on the next statement. + // See comment in |commitBranchState| + defer func() { + if err == nil { + ctx.SetTransaction(nil) + } + }() + if d.BatchMode() == Batched { for _, db := range d.provider.DoltDatabases() { err := d.Flush(ctx, db.Name()) @@ -412,12 +422,13 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) er dirtyBranchState := dirties[0] if peformDoltCommitInt == 1 { // if the dirty working set doesn't belong to the currently checked out branch, that's an error - err2 := d.validateDoltCommit(ctx, dirtyBranchState) - if err2 != nil { - return err2 + err = d.validateDoltCommit(ctx, dirtyBranchState) + if err != nil { + return err } - pendingCommit, err := d.PendingCommitAllStaged(ctx, dirtyBranchState, actions.CommitStagedProps{ + var pendingCommit *doltdb.PendingCommit + pendingCommit, err = d.PendingCommitAllStaged(ctx, dirtyBranchState, actions.CommitStagedProps{ Message: "Transaction commit", Date: ctx.QueryTime(), AllowEmpty: false, @@ -500,6 +511,7 @@ func (d *DoltSession) CommitWorkingSet(ctx *sql.Context, dbName string, tx sql.T return err } +// commitWorkingSet commits the working set for the branch state given, without creating a new dolt commit. func (d *DoltSession) commitWorkingSet(ctx *sql.Context, branchState *branchState, tx sql.Transaction) error { commitFunc := func(ctx *sql.Context, dtx *DoltTransaction, workingSet *doltdb.WorkingSet) (*doltdb.WorkingSet, *doltdb.Commit, error) { ws, err := dtx.Commit(ctx, workingSet, branchState.dbState.dbName) @@ -528,11 +540,6 @@ func (d *DoltSession) DoltCommit( return nil, nil, err } - // Unlike normal COMMIT statements, CALL DOLT_COMMIT() doesn't get the current transaction cleared out by the query - // engine, so we do it here. - // TODO: the engine needs to manage this - ctx.SetTransaction(nil) - return ws, commit, err } @@ -559,8 +566,12 @@ func (d *DoltSession) commitBranchState( if err != nil { return nil, err } - - branchState.dirty = false + + // Anything that commits a transaction needs its current transaction state cleared so that the next statement starts + // a new transaction. This should in principle be done by the engine, but it currently only understands explicit + // COMMIT statements. Any other statements that commit a transaction, including stored procedures, needs to do this + // themselves. + ctx.SetTransaction(nil) return newCommit, nil } From ba9605da70a15048cd34d541e6c4607ecef25a4e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 30 May 2023 16:22:24 -0700 Subject: [PATCH 110/167] Branch-aware privileges test --- .../sqle/enginetest/privilege_test.go | 590 ++++++++++++++++++ 1 file changed, 590 insertions(+) create mode 100755 go/libraries/doltcore/sqle/enginetest/privilege_test.go diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go new file mode 100755 index 0000000000..5cdbdb7483 --- /dev/null +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -0,0 +1,590 @@ +// Copyright 2022 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package enginetest + +import ( + "testing" + + "github.com/dolthub/go-mysql-server/enginetest" + "github.com/dolthub/go-mysql-server/enginetest/queries" + "github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup" + "github.com/dolthub/go-mysql-server/sql" + "github.com/dolthub/go-mysql-server/sql/mysql_db" + "github.com/dolthub/go-mysql-server/sql/types" + "github.com/stretchr/testify/require" +) + +var revisionDatabasePrivsSetupPrefix = []string{ + "call dolt_branch('b1')", + "use mydb/b1", +} + +// The subset of tests in priv_auth_queries.go to run with alternate branch logic. Not all of them are suitable +// because they use non-qualified database names in their queries +// TODO: non-* versions of these tests +var revisionDatabasePrivilegeScriptNames = []string{ + "Binlog replication privileges", + "Valid users without privileges may use the dual table", + "Basic SELECT and INSERT privilege checking", + "Basic revoke SELECT privilege", + "Basic revoke all global static privileges", + "Grant Role with SELECT Privilege", + "Revoke role currently granted to a user", + "Drop role currently granted to a user", + "Show grants on a user from the root account", + // "Anonymous user" -- remove me after conversion + // "IPv4 Loopback == localhost", + "information_schema.columns table 'privileges' column gets correct values", + "information_schema.column_statistics shows columns with privileges only", + "information_schema.statistics shows tables with privileges only", +} + +func TestRevisionDatabasePrivileges(t *testing.T) { + testsToRun := make(map[string]bool) + for _, name := range revisionDatabasePrivilegeScriptNames { + testsToRun[name] = true + } + + var scripts []queries.UserPrivilegeTest + for _, script := range queries.UserPrivTests { + if testsToRun[script.Name] { + scripts = append(scripts, script) + } + } + + require.Equal(t, len(scripts), len(testsToRun), + "Error in test setup: one or more expected tests not found. " + + "Did the name of a test change?") + + for _, script := range scripts { + harness := newDoltHarness(t) + harness.Setup(setup.MydbData, setup.MytableData) + t.Run(script.Name, func(t *testing.T) { + engine := mustNewEngine(t, harness) + defer engine.Close() + + ctx := enginetest.NewContext(harness) + ctx.NewCtxWithClient(sql.Client{ + User: "root", + Address: "localhost", + }) + engine.Analyzer.Catalog.MySQLDb.AddRootAccount() + engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) + + for _, statement := range append(revisionDatabasePrivsSetupPrefix, script.SetUpScript...) { + if harness.SkipQueryTest(statement) { + t.Skip() + } + enginetest.RunQueryWithContext(t, engine, harness, ctx, statement) + } + + for _, assertion := range script.Assertions { + if harness.SkipQueryTest(assertion.Query) { + t.Skipf("Skipping query %s", assertion.Query) + } + + user := assertion.User + host := assertion.Host + if user == "" { + user = "root" + } + if host == "" { + host = "localhost" + } + ctx := enginetest.NewContextWithClient(harness, sql.Client{ + User: user, + Address: host, + }) + ctx.SetCurrentDatabase("mydb/b1") + + if assertion.ExpectedErr != nil { + t.Run(assertion.Query, func(t *testing.T) { + enginetest.AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, assertion.ExpectedErr) + }) + } else if assertion.ExpectedErrStr != "" { + t.Run(assertion.Query, func(t *testing.T) { + enginetest.AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, nil, assertion.ExpectedErrStr) + }) + } else { + t.Run(assertion.Query, func(t *testing.T) { + enginetest.TestQueryWithContext(t, ctx, engine, harness, assertion.Query, assertion.Expected, nil, nil) + }) + } + } + }) + } +} + +var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ + { + Name: "Basic database and table name visibility", + SetUpScript: []string{ + "use mydb", + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1);", + "call dolt_branch('b1')", + "use mydb/b1", + "call dolt_commit('-Am', 'first commit')", + "CREATE USER tester@localhost;", + "CREATE ROLE test_role;", + "GRANT SELECT ON mydb.* TO test_role;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*1*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*1*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT SELECT ON *.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*2*/", + Expected: []sql.Row{{1}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*2*/", + ExpectedErr: sql.ErrTableNotFound, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE SELECT ON *.* FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { // Ensure we've reverted to initial state (all SELECTs after REVOKEs are doing this) + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*3*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*3*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT SELECT ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM mydb.test;/*4*/", + Expected: []sql.Row{{1}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*4*/", + ExpectedErr: sql.ErrTableNotFound, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE SELECT ON mydb.* FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*5*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*5*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT SELECT ON mydb.test TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*6*/", + Expected: []sql.Row{{1}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*6*/", + ExpectedErr: sql.ErrTableAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE SELECT ON mydb.test FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*7*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*7*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT SELECT ON mydb.test2 TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*8*/", + ExpectedErr: sql.ErrTableAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*8*/", + ExpectedErr: sql.ErrTableNotFound, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE SELECT ON mydb.test2 FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*9*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*9*/", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT test_role TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;/*10*/", + Expected: []sql.Row{{1}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test2;/*10*/", + ExpectedErr: sql.ErrTableNotFound, + }, + }, + }, + { + Name: "Basic SELECT and INSERT privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "INSERT INTO test VALUES (4);", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT INSERT ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "INSERT INTO test VALUES (4);", + Expected: []sql.Row{{types.NewOkResult(1)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}, {3}, {4}}, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT SELECT ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}, {3}, {4}}, + }, + }, + }, + { + Name: "Basic revoke SELECT privilege", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + "GRANT SELECT ON mydb.* TO tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}, {3}}, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT User, Host, Select_priv FROM mysql.user WHERE User = 'tester';", + Expected: []sql.Row{{"tester", "localhost", uint16(2)}}, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE SELECT ON mydb.* FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT User, Host, Select_priv FROM mysql.user WHERE User = 'tester';", + Expected: []sql.Row{{"tester", "localhost", uint16(1)}}, + }, + }, + }, + { + Name: "Grant Role with SELECT Privilege", + SetUpScript: []string{ + "SET @@GLOBAL.activate_all_roles_on_login = true;", + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + "CREATE ROLE test_role;", + "GRANT SELECT ON mydb.* TO test_role;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT COUNT(*) FROM mysql.role_edges;", + Expected: []sql.Row{{0}}, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT test_role TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT * FROM mysql.role_edges;", + Expected: []sql.Row{{"%", "test_role", "localhost", "tester", uint16(1)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}, {3}}, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT User, Host, Select_priv FROM mysql.user WHERE User = 'tester';", + Expected: []sql.Row{{"tester", "localhost", uint16(1)}}, + }, + }, + }, + { + Name: "Revoke role currently granted to a user", + SetUpScript: []string{ + "SET @@GLOBAL.activate_all_roles_on_login = true;", + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + "CREATE ROLE test_role;", + "GRANT SELECT ON mydb.* TO test_role;", + "GRANT test_role TO tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}, {3}}, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT * FROM mysql.role_edges;", + Expected: []sql.Row{{"%", "test_role", "localhost", "tester", uint16(1)}}, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE test_role FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT COUNT(*) FROM mysql.role_edges;", + Expected: []sql.Row{{0}}, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT COUNT(*) FROM mysql.user WHERE User = 'test_role';", + Expected: []sql.Row{{1}}, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT COUNT(*) FROM mysql.user WHERE User = 'tester';", + Expected: []sql.Row{{1}}, + }, + }, + }, +} + +func TestDoltOnlyRevisionDatabasePrivileges(t *testing.T) { + for _, script := range DoltOnlyRevisionDbPrivilegeTests { + harness := newDoltHarness(t) + harness.Setup(setup.MydbData, setup.MytableData) + t.Run(script.Name, func(t *testing.T) { + engine := mustNewEngine(t, harness) + defer engine.Close() + + ctx := enginetest.NewContext(harness) + ctx.NewCtxWithClient(sql.Client{ + User: "root", + Address: "localhost", + }) + engine.Analyzer.Catalog.MySQLDb.AddRootAccount() + engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) + + for _, statement := range script.SetUpScript { + if harness.SkipQueryTest(statement) { + t.Skip() + } + enginetest.RunQueryWithContext(t, engine, harness, ctx, statement) + } + + for _, assertion := range script.Assertions { + if harness.SkipQueryTest(assertion.Query) { + t.Skipf("Skipping query %s", assertion.Query) + } + + user := assertion.User + host := assertion.Host + if user == "" { + user = "root" + } + if host == "" { + host = "localhost" + } + ctx := enginetest.NewContextWithClient(harness, sql.Client{ + User: user, + Address: host, + }) + + if assertion.ExpectedErr != nil { + t.Run(assertion.Query, func(t *testing.T) { + enginetest.AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, assertion.ExpectedErr) + }) + } else if assertion.ExpectedErrStr != "" { + t.Run(assertion.Query, func(t *testing.T) { + enginetest.AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, nil, assertion.ExpectedErrStr) + }) + } else { + t.Run(assertion.Query, func(t *testing.T) { + enginetest.TestQueryWithContext(t, ctx, engine, harness, assertion.Query, assertion.Expected, nil, nil) + }) + } + } + }) + } +} \ No newline at end of file From ba47a139fc3fed2823fcbccf00bdb7d1b27517a1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 12:29:28 -0700 Subject: [PATCH 111/167] More privilege changes --- go/libraries/doltcore/sqle/database.go | 7 ++ .../sqle/enginetest/privilege_test.go | 116 ++++++++++++++++-- 2 files changed, 112 insertions(+), 11 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 4d8e922f33..088766089b 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -75,6 +75,7 @@ var _ sql.TriggerDatabase = Database{} var _ sql.VersionedDatabase = Database{} var _ sql.ViewDatabase = Database{} var _ sql.EventDatabase = Database{} +var _ sql.AliasedDatabase = Database{} type ReadOnlyDatabase struct { Database @@ -145,6 +146,12 @@ func (db Database) Name() string { return db.RequestedName() } +// AliasedName is what allows databases named e.g. `mydb/b1` to work with the grant and info schema tables that expect +// a base (no revision qualifier) db name +func (db Database) AliasedName() string { + return db.name +} + // RevisionQualifiedName returns the name of this database including its revision qualifier, if any. This method should // be used whenever accessing internal state of a database and its tables. func (db Database) RevisionQualifiedName() string { diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 5cdbdb7483..933ae6982c 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -127,6 +127,8 @@ func TestRevisionDatabasePrivileges(t *testing.T) { } } +// Privilege test scripts for revision databases. Due to limitations in test construction, test assertions are always +// performed with current db = mydb/b1, write scripts accordingly var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { Name: "Basic database and table name visibility", @@ -134,9 +136,9 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ "use mydb", "CREATE TABLE test (pk BIGINT PRIMARY KEY);", "INSERT INTO test VALUES (1);", + "call dolt_commit('-Am', 'first commit')", "call dolt_branch('b1')", "use mydb/b1", - "call dolt_commit('-Am', 'first commit')", "CREATE USER tester@localhost;", "CREATE ROLE test_role;", "GRANT SELECT ON mydb.* TO test_role;", @@ -157,7 +159,7 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "root", Host: "localhost", - Query: "GRANT SELECT ON *.* TO tester@localhost;", + Query: "GRANT SELECT ON mydb.* TO tester@localhost;", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { @@ -175,7 +177,7 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "root", Host: "localhost", - Query: "REVOKE SELECT ON *.* FROM tester@localhost;", + Query: "REVOKE SELECT ON mydb.* FROM tester@localhost;", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { // Ensure we've reverted to initial state (all SELECTs after REVOKEs are doing this) @@ -373,6 +375,104 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ }, }, }, + { + Name: "Basic UPDATE privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "UPDATE test set pk = 4 where pk = 3;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT UPDATE ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "INSERT INTO test VALUES (4);", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "UPDATE test set pk = 4 where pk = 3;", + Expected: []sql.Row{{types.NewOkResult(1)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}, {4}}, + }, + }, + }, + { + Name: "Basic DELETE privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "DELETE from test where pk = 3;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT DELETE ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "INSERT INTO test VALUES (4);", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "tester", + Host: "localhost", + Query: "DELETE from test where pk = 3;", + Expected: []sql.Row{{types.NewOkResult(1)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "SELECT * FROM test;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "SELECT * FROM test;", + Expected: []sql.Row{{1}, {2}}, + }, + }, + }, { Name: "Basic revoke SELECT privilege", SetUpScript: []string{ @@ -395,7 +495,7 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ User: "root", Host: "localhost", Query: "SELECT User, Host, Select_priv FROM mysql.user WHERE User = 'tester';", - Expected: []sql.Row{{"tester", "localhost", uint16(2)}}, + Expected: []sql.Row{{"tester", "localhost", uint16(1)}}, }, { User: "root", @@ -547,17 +647,10 @@ func TestDoltOnlyRevisionDatabasePrivileges(t *testing.T) { engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) for _, statement := range script.SetUpScript { - if harness.SkipQueryTest(statement) { - t.Skip() - } enginetest.RunQueryWithContext(t, engine, harness, ctx, statement) } for _, assertion := range script.Assertions { - if harness.SkipQueryTest(assertion.Query) { - t.Skipf("Skipping query %s", assertion.Query) - } - user := assertion.User host := assertion.Host if user == "" { @@ -570,6 +663,7 @@ func TestDoltOnlyRevisionDatabasePrivileges(t *testing.T) { User: user, Address: host, }) + ctx.SetCurrentDatabase("mydb/b1") if assertion.ExpectedErr != nil { t.Run(assertion.Query, func(t *testing.T) { From 1480414bb8c57abf9758d5127019e3dea108a589 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 12:44:06 -0700 Subject: [PATCH 112/167] Fixed update test --- .../doltcore/sqle/enginetest/privilege_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 933ae6982c..27e1b294e8 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -22,6 +22,7 @@ import ( "github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/mysql_db" + "github.com/dolthub/go-mysql-server/sql/plan" "github.com/dolthub/go-mysql-server/sql/types" "github.com/stretchr/testify/require" ) @@ -402,13 +403,19 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ User: "tester", Host: "localhost", Query: "INSERT INTO test VALUES (4);", - ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + ExpectedErr: sql.ErrPrivilegeCheckFailed, }, { User: "tester", Host: "localhost", Query: "UPDATE test set pk = 4 where pk = 3;", - Expected: []sql.Row{{types.NewOkResult(1)}}, + Expected: []sql.Row{{types.OkResult{ + RowsAffected: 1, + Info: plan.UpdateInfo{ + Matched: 1, + Updated: 1, + }, + }}}, }, { User: "tester", From 1411cd08d03b84f4233ea76288d9a4cfecb1b304 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 13:13:17 -0700 Subject: [PATCH 113/167] Fixed delete priv test --- go/libraries/doltcore/sqle/enginetest/privilege_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 27e1b294e8..eb7dfc4063 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -458,7 +458,7 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ User: "tester", Host: "localhost", Query: "INSERT INTO test VALUES (4);", - ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + ExpectedErr: sql.ErrPrivilegeCheckFailed, }, { User: "tester", From f5c503f81eafca875d3b6e68702c4de5b2523169 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 14:08:53 -0700 Subject: [PATCH 114/167] tests for ddl statements --- .../sqle/enginetest/privilege_test.go | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index eb7dfc4063..17cc5a15e2 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -480,6 +480,119 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ }, }, }, + { + Name: "Basic CREATE TABLE privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "CREATE TABLE t2 (a int primary key);", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT CREATE ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "CREATE TABLE t2 (a int primary key);", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "show tables;", + Expected: []sql.Row{{"mytable"}, {"test"}, {"t2"}}, + }, + }, + }, + { + Name: "Basic DROP TABLE privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "DROP TABLE test;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT DROP ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "DROP TABLE TEST", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "show tables;", + Expected: []sql.Row{{"mytable"}}, + }, + }, + }, + { + Name: "Basic ALTER TABLE privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY);", + "INSERT INTO test VALUES (1), (2), (3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "ALTER TABLE test add column a int;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT CREATE ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "ALTER TABLE test add column a int;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "desc test;", + Expected: []sql.Row{ + {"pk", "bigint", "NO", "PRI", "NULL"}, + {"a", "int", "NO", "PRI", "NULL"}, + }, + }, + }, + }, { Name: "Basic revoke SELECT privilege", SetUpScript: []string{ From 9117ec2a8f139439cafc9b82a571f8ff36e2f452 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 14:30:49 -0700 Subject: [PATCH 115/167] Fixed several instances of base name being used instead of revision qualified name. Renamed db.name to db.baseName --- go/libraries/doltcore/sqle/database.go | 31 ++++++++++--------- .../doltcore/sqle/database_provider.go | 10 +++--- .../sqle/enginetest/privilege_test.go | 1 + .../doltcore/sqle/read_replica_database.go | 2 +- go/libraries/doltcore/sqle/tables.go | 4 +-- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 088766089b..1914edf0aa 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -48,7 +48,7 @@ var ErrSystemTableAlter = errors.NewKind("Cannot alter table %s: system tables c // Database implements sql.Database for a dolt DB. type Database struct { - name string + baseName string requestedName string ddb *doltdb.DoltDB rsr env.RepoStateReader @@ -117,7 +117,7 @@ func NewDatabase(ctx context.Context, name string, dbData env.DbData, editOpts e } return Database{ - name: name, + baseName: name, requestedName: name, ddb: dbData.Ddb, rsr: dbData.Rsr, @@ -149,16 +149,16 @@ func (db Database) Name() string { // AliasedName is what allows databases named e.g. `mydb/b1` to work with the grant and info schema tables that expect // a base (no revision qualifier) db name func (db Database) AliasedName() string { - return db.name + return db.baseName } // RevisionQualifiedName returns the name of this database including its revision qualifier, if any. This method should // be used whenever accessing internal state of a database and its tables. func (db Database) RevisionQualifiedName() string { if db.revision == "" { - return db.name + return db.baseName } - return db.name + dsess.DbRevisionDelimiter + db.revision + return db.baseName + dsess.DbRevisionDelimiter + db.revision } func (db Database) RequestedName() string { @@ -433,6 +433,7 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds return dt, found, nil } + // TODO: this should reuse the root, not lookup the db state again return db.getTable(ctx, root, tblName) } @@ -554,7 +555,7 @@ func (db Database) GetTableNamesAsOf(ctx *sql.Context, time interface{}) ([]stri return filterDoltInternalTables(tblNames), nil } -// getTable returns the user table with the given name from the root given +// getTable returns the user table with the given baseName from the root given func (db Database) getTable(ctx *sql.Context, root *doltdb.RootValue, tableName string) (sql.Table, bool, error) { sess := dsess.DSessFromSess(ctx.Session) dbState, ok, err := sess.LookupDbState(ctx, db.RevisionQualifiedName()) @@ -562,7 +563,7 @@ func (db Database) getTable(ctx *sql.Context, root *doltdb.RootValue, tableName return nil, false, err } if !ok { - return nil, false, fmt.Errorf("no state for database %s", db.name) + return nil, false, fmt.Errorf("no state for database %s", db.RevisionQualifiedName()) } key, err := doltdb.NewDataCacheKey(root) @@ -694,7 +695,7 @@ func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) { // convenience. func (db Database) SetRoot(ctx *sql.Context, newRoot *doltdb.RootValue) error { sess := dsess.DSessFromSess(ctx.Session) - return sess.SetRoot(ctx, db.name, newRoot) + return sess.SetRoot(ctx, db.RevisionQualifiedName(), newRoot) } // GetHeadRoot returns root value for the current session head @@ -720,7 +721,7 @@ func (db Database) DropTable(ctx *sql.Context, tableName string) error { return db.dropTable(ctx, tableName) } -// dropTable drops the table with the name given, without any business logic checks +// dropTable drops the table with the baseName given, without any business logic checks func (db Database) dropTable(ctx *sql.Context, tableName string) error { ds := dsess.DSessFromSess(ctx.Session) if _, ok := ds.GetTemporaryTable(ctx, db.Name(), tableName); ok { @@ -754,7 +755,7 @@ func (db Database) dropTable(ctx *sql.Context, tableName string) error { } if schema.HasAutoIncrement(sch) { - ddb, _ := ds.GetDoltDB(ctx, db.name) + ddb, _ := ds.GetDoltDB(ctx, db.RevisionQualifiedName()) err = db.removeTableFromAutoIncrementTracker(ctx, tableName, ddb, ws.Ref()) if err != nil { return err @@ -857,7 +858,7 @@ func (db Database) CreateIndexedTable(ctx *sql.Context, tableName string, sch sq return db.createIndexedSqlTable(ctx, tableName, sch, idxDef, collation) } -// Unlike the exported version CreateTable, createSqlTable doesn't enforce any table name checks. +// Unlike the exported version CreateTable, createSqlTable doesn't enforce any table baseName checks. func (db Database) createSqlTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, collation sql.CollationID) error { ws, err := db.GetWorkingSet(ctx) if err != nil { @@ -899,7 +900,7 @@ func (db Database) createSqlTable(ctx *sql.Context, tableName string, sch sql.Pr return db.createDoltTable(ctx, tableName, root, doltSch) } -// Unlike the exported version CreateTable, createSqlTable doesn't enforce any table name checks. +// Unlike the exported version CreateTable, createSqlTable doesn't enforce any table baseName checks. func (db Database) createIndexedSqlTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, idxDef sql.IndexDef, collation sql.CollationID) error { ws, err := db.GetWorkingSet(ctx) if err != nil { @@ -947,7 +948,7 @@ func (db Database) createIndexedSqlTable(ctx *sql.Context, tableName string, sch return db.createDoltTable(ctx, tableName, root, doltSch) } -// createDoltTable creates a table on the database using the given dolt schema while not enforcing table name checks. +// createDoltTable creates a table on the database using the given dolt schema while not enforcing table baseName checks. func (db Database) createDoltTable(ctx *sql.Context, tableName string, root *doltdb.RootValue, doltSch schema.Schema) error { if exists, err := root.HasTable(ctx, tableName); err != nil { return err @@ -1159,7 +1160,7 @@ func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) { // it can exist in a sql session later. Returns sql.ErrExistingView if a view // with that name already exists. func (db Database) CreateView(ctx *sql.Context, name string, selectStatement, createViewStmt string) error { - err := sql.ErrExistingView.New(db.name, name) + err := sql.ErrExistingView.New(db.Name(), name) return db.addFragToSchemasTable(ctx, "view", name, createViewStmt, time.Unix(0, 0).UTC(), err) } @@ -1167,7 +1168,7 @@ func (db Database) CreateView(ctx *sql.Context, name string, selectStatement, cr // dolt database. Returns sql.ErrNonExistingView if the view did not // exist. func (db Database) DropView(ctx *sql.Context, name string) error { - err := sql.ErrViewDoesNotExist.New(db.name, name) + err := sql.ErrViewDoesNotExist.New(db.baseName, name) return db.dropFragFromSchemasTable(ctx, "view", name, err) } diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 5200a8ca5b..373f5c1ccf 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1284,7 +1284,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s switch v := srcDb.(type) { case ReadOnlyDatabase: db := Database{ - name: srcDb.Name(), + baseName: srcDb.Name(), requestedName: requestedName, ddb: v.ddb, rsw: static, @@ -1297,7 +1297,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s return ReadOnlyDatabase{db}, nil case Database: return Database{ - name: srcDb.Name(), + baseName: srcDb.Name(), requestedName: requestedName, ddb: v.ddb, rsw: static, @@ -1310,7 +1310,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s case ReadReplicaDatabase: return ReadReplicaDatabase{ Database: Database{ - name: srcDb.Name(), + baseName: srcDb.Name(), requestedName: requestedName, ddb: v.ddb, rsw: static, @@ -1395,7 +1395,7 @@ func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.I func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { return ReadOnlyDatabase{Database: Database{ - name: srcDb.Name(), + baseName: srcDb.Name(), requestedName: requestedName, ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, @@ -1436,7 +1436,7 @@ func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.In func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { return ReadOnlyDatabase{Database: Database{ - name: srcDb.Name(), + baseName: srcDb.Name(), requestedName: requestedName, ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 17cc5a15e2..fdfddfe718 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -593,6 +593,7 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ }, }, }, + // TODO: indexes, constraints { Name: "Basic revoke SELECT privilege", SetUpScript: []string{ diff --git a/go/libraries/doltcore/sqle/read_replica_database.go b/go/libraries/doltcore/sqle/read_replica_database.go index 805c3ac349..29daf998e0 100644 --- a/go/libraries/doltcore/sqle/read_replica_database.go +++ b/go/libraries/doltcore/sqle/read_replica_database.go @@ -115,7 +115,7 @@ func (rrd ReadReplicaDatabase) PullFromRemote(ctx *sql.Context) error { } dSess := dsess.DSessFromSess(ctx.Session) - currentBranchRef, err := dSess.CWBHeadRef(ctx, rrd.name) + currentBranchRef, err := dSess.CWBHeadRef(ctx, rrd.baseName) if err != nil && !dsess.IgnoreReplicationErrors() { return err } else if err != nil { diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 5a85b4ecad..0b04a552ef 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -1680,7 +1680,7 @@ func (t *AlterableDoltTable) ModifyColumn(ctx *sql.Context, columnName string, c if existingCol.AutoIncrement && !col.AutoIncrement { // TODO: this isn't transactional, and it should be sess := dsess.DSessFromSess(ctx.Session) - ddb, _ := sess.GetDoltDB(ctx, t.db.name) + ddb, _ := sess.GetDoltDB(ctx, t.db.RevisionQualifiedName()) err = t.db.removeTableFromAutoIncrementTracker(ctx, t.Name(), ddb, ws.Ref()) if err != nil { return err @@ -2385,7 +2385,7 @@ func (t *AlterableDoltTable) updateFromRoot(ctx *sql.Context, root *doltdb.RootV sess := dsess.DSessFromSess(ctx.Session) dbState, ok, err := sess.LookupDbState(ctx, t.db.RevisionQualifiedName()) if !ok { - return fmt.Errorf("no db state found for %s", t.db.name) + return fmt.Errorf("no db state found for %s", t.db.RevisionQualifiedName()) } dbState.SessionCache().ClearTableCache() From e0d16078ef4af9ee3375f6fa00e036cfd46d5729 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 15:36:26 -0700 Subject: [PATCH 116/167] Proactively cleaning up some more instances of usig the unqualified db name --- .../doltcore/sqle/database_provider.go | 32 +++++++------------ go/libraries/doltcore/sqle/dsess/session.go | 6 ++-- .../doltcore/sqle/dsess/transactions.go | 5 +-- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 373f5c1ccf..6a65440699 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -260,12 +260,7 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database showBranches, _ := dsess.GetBooleanSystemVar(ctx, dsess.ShowBranchDatabases) all = make([]sql.Database, 0, len(p.databases)) - var foundDatabase bool - currDb := strings.ToLower(ctx.GetCurrentDatabase()) for _, db := range p.databases { - if strings.ToLower(db.Name()) == currDb { - foundDatabase = true - } all = append(all, db) if showBranches { @@ -276,16 +271,6 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database continue } all = append(all, revisionDbs...) - - // if one of the revisions we just expanded matches the curr db, mark it so we don't double-include that - // revision db - if !foundDatabase && currDb != "" { - for _, revisionDb := range revisionDbs { - if strings.ToLower(revisionDb.Name()) == currDb { - foundDatabase = true - } - } - } } } p.mu.RUnlock() @@ -1080,7 +1065,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds usingDefaultBranch = true // First check the global variable for the default branch - _, val, ok := sql.SystemVariables.GetGlobal(dsess.DefaultBranchKey(db.Name())) + _, val, ok := sql.SystemVariables.GetGlobal(dsess.DefaultBranchKey(baseName)) if ok { head = val.(string) branchRef, err := ref.Parse(head) @@ -1280,11 +1265,14 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s RepoStateWriter: srcDb.DbData().Rsw, RepoStateReader: srcDb.DbData().Rsr, } + + baseName, _ := dsess.SplitRevisionDbName(srcDb.Name()) + // TODO: we need a base name method here switch v := srcDb.(type) { case ReadOnlyDatabase: db := Database{ - baseName: srcDb.Name(), + baseName: baseName, requestedName: requestedName, ddb: v.ddb, rsw: static, @@ -1297,7 +1285,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s return ReadOnlyDatabase{db}, nil case Database: return Database{ - baseName: srcDb.Name(), + baseName: baseName, requestedName: requestedName, ddb: v.ddb, rsw: static, @@ -1310,7 +1298,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s case ReadReplicaDatabase: return ReadReplicaDatabase{ Database: Database{ - baseName: srcDb.Name(), + baseName: baseName, requestedName: requestedName, ddb: v.ddb, rsw: static, @@ -1394,8 +1382,9 @@ func initialStateForBranchDb(ctx *sql.Context, srcDb dsess.SqlDatabase) (dsess.I } func revisionDbForTag(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { + baseName, _ := dsess.SplitRevisionDbName(srcDb.Name()) return ReadOnlyDatabase{Database: Database{ - baseName: srcDb.Name(), + baseName: baseName, requestedName: requestedName, ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, @@ -1435,8 +1424,9 @@ func initialStateForTagDb(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.In } func revisionDbForCommit(ctx context.Context, srcDb Database, revSpec string, requestedName string) (ReadOnlyDatabase, error) { + baseName, _ := dsess.SplitRevisionDbName(srcDb.Name()) return ReadOnlyDatabase{Database: Database{ - baseName: srcDb.Name(), + baseName: baseName, requestedName: requestedName, ddb: srcDb.DbData().Ddb, rsw: srcDb.DbData().Rsw, diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index b70d2d8dc3..b34a5a5a4f 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -389,7 +389,7 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) (e if d.BatchMode() == Batched { for _, db := range d.provider.DoltDatabases() { - err := d.Flush(ctx, db.Name()) + err = d.Flush(ctx, db.Name()) if err != nil { return err } @@ -1110,11 +1110,11 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { // addDB adds the database given to this session. This establishes a starting root value for this session, as well as // other state tracking metadata. func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { - DefineSystemVariablesForDB(db.Name()) - revisionQualifiedName := db.Name() baseName, _ := SplitRevisionDbName(revisionQualifiedName) + DefineSystemVariablesForDB(baseName) + // TODO: odd that we need to tell the DB what its own revision is here dbState, err := db.InitialDBState(ctx, db.Revision()) if err != nil { diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 0da9a9cfe4..dd72525516 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -103,8 +103,9 @@ func NewDoltTransaction( return nil, err } - startPoints[strings.ToLower(db.Name())] = dbRoot{ - dbName: db.Name(), + baseName, _ := SplitRevisionDbName(db.Name()) + startPoints[strings.ToLower(baseName)] = dbRoot{ + dbName: baseName, rootHash: nomsRoot, db: db.DbData().Ddb, } From b0b313cbcc8209ce76ab67d27711b295c7d1eb03 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 15:39:35 -0700 Subject: [PATCH 117/167] Fixed test --- go/libraries/doltcore/sqle/enginetest/privilege_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index fdfddfe718..2a518dd984 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -573,7 +573,7 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "root", Host: "localhost", - Query: "GRANT CREATE ON mydb.* TO tester@localhost;", + Query: "GRANT ALTER ON mydb.* TO tester@localhost;", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { @@ -587,8 +587,8 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ Host: "localhost", Query: "desc test;", Expected: []sql.Row{ - {"pk", "bigint", "NO", "PRI", "NULL"}, - {"a", "int", "NO", "PRI", "NULL"}, + {"pk", "bigint", "NO", "PRI", "NULL", ""}, + {"a", "int", "YES", "", "NULL", ""}, }, }, }, From fe60855d35ea4cb765e37bcfb75670915f21f0e0 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 16:17:23 -0700 Subject: [PATCH 118/167] Privilege tests for indexes and constraints --- .../sqle/enginetest/privilege_test.go | 220 +++++++++++++++++- 1 file changed, 219 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 2a518dd984..0fa203cbff 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -593,7 +593,225 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ }, }, }, - // TODO: indexes, constraints + { + Name: "Basic INDEX privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY, a int);", + "INSERT INTO test VALUES (1,1), (2,2), (3,3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "create index t1 on test(a) ;", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT select ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "create index t1 on test(a) ;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT index ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "create index t1 on test(a) ;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "desc test;", + Expected: []sql.Row{ + {"pk", "bigint", "NO", "PRI", "NULL", ""}, + {"a", "int", "YES", "MUL", "NULL", ""}, + }, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE index ON mydb.* FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "drop index t1 on test;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT index ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "drop index t1 on test;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "desc test;", + Expected: []sql.Row{ + {"pk", "bigint", "NO", "PRI", "NULL", ""}, + {"a", "int", "YES", "", "NULL", ""}, + }, + }, + }, + }, + { + Name: "Basic constraint privilege checking", + SetUpScript: []string{ + "CREATE TABLE test (pk BIGINT PRIMARY KEY, a int);", + "INSERT INTO test VALUES (1,1), (2,2), (3,3);", + "call dolt_commit('-Am', 'first commit');", + "call dolt_branch('b1')", + "use mydb/b1;", + "CREATE USER tester@localhost;", + }, + Assertions: []queries.UserPrivilegeTestAssertion{ + { + User: "tester", + Host: "localhost", + Query: "alter table test add constraint CHECK (NULL = NULL);", + ExpectedErr: sql.ErrDatabaseAccessDeniedForUser, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT select ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test add constraint CHECK (NULL = NULL);", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT alter ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test add constraint chk1 CHECK (a < 10);", + Expected: []sql.Row{}, + }, + { + User: "tester", + Host: "localhost", + Query: "show create table test;", + Expected: []sql.Row{ + {"test", "CREATE TABLE `test` (\n" + + " `pk` bigint NOT NULL,\n" + + " `a` int,\n" + + " PRIMARY KEY (`pk`),\n" + + " CONSTRAINT `chk1` CHECK ((`a` < 10))\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, + }, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE alter ON mydb.* FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test drop check chk1;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT alter ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test drop check chk1;", + Expected: []sql.Row{}, + }, + { + User: "tester", + Host: "localhost", + Query: "show create table test;", + Expected: []sql.Row{ + {"test", "CREATE TABLE `test` (\n" + + " `pk` bigint NOT NULL,\n" + + " `a` int,\n" + + " PRIMARY KEY (`pk`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, + }, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test add constraint chk1 CHECK (a < 10);", + Expected: []sql.Row{}, + }, + { + User: "root", + Host: "localhost", + Query: "REVOKE alter ON mydb.* FROM tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test drop constraint chk1;", + ExpectedErr: sql.ErrPrivilegeCheckFailed, + }, + { + User: "root", + Host: "localhost", + Query: "GRANT alter ON mydb.* TO tester@localhost;", + Expected: []sql.Row{{types.NewOkResult(0)}}, + }, + { + User: "tester", + Host: "localhost", + Query: "alter table test drop constraint chk1;", + Expected: []sql.Row{}, + }, + { + User: "tester", + Host: "localhost", + Query: "show create table test;", + Expected: []sql.Row{ + {"test", "CREATE TABLE `test` (\n" + + " `pk` bigint NOT NULL,\n" + + " `a` int,\n" + + " PRIMARY KEY (`pk`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, + }, + }, + }, + }, { Name: "Basic revoke SELECT privilege", SetUpScript: []string{ From 2a8d7ac831ff9d1661d008e432aca5de5b4706eb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 31 May 2023 17:14:16 -0700 Subject: [PATCH 119/167] Cleanup --- go/libraries/doltcore/sqle/enginetest/privilege_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 0fa203cbff..2d16d2c547 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -34,7 +34,6 @@ var revisionDatabasePrivsSetupPrefix = []string{ // The subset of tests in priv_auth_queries.go to run with alternate branch logic. Not all of them are suitable // because they use non-qualified database names in their queries -// TODO: non-* versions of these tests var revisionDatabasePrivilegeScriptNames = []string{ "Binlog replication privileges", "Valid users without privileges may use the dual table", @@ -45,13 +44,13 @@ var revisionDatabasePrivilegeScriptNames = []string{ "Revoke role currently granted to a user", "Drop role currently granted to a user", "Show grants on a user from the root account", - // "Anonymous user" -- remove me after conversion - // "IPv4 Loopback == localhost", "information_schema.columns table 'privileges' column gets correct values", "information_schema.column_statistics shows columns with privileges only", "information_schema.statistics shows tables with privileges only", } +// TestRevisionDatabasePrivileges is a spot-check of privilege checking on the original privilege test scripts, +// but with a revisioned database as the current db func TestRevisionDatabasePrivileges(t *testing.T) { testsToRun := make(map[string]bool) for _, name := range revisionDatabasePrivilegeScriptNames { From 76ca92ea2dea69e6f5f40f9ec087cd846e541f4e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 10:04:43 -0700 Subject: [PATCH 120/167] AllDatabases now returns the current database version of any database: e.g. if mydb/foo is in use, we return a revision db on branch foo for mydb (instead of mydb/main) --- go/libraries/doltcore/sqle/database_provider.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 6a65440699..069b522980 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -255,12 +255,27 @@ func (p DoltDatabaseProvider) HasDatabase(ctx *sql.Context, name string) bool { } func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database) { + currentDb := ctx.GetCurrentDatabase() + currBase, currRev := dsess.SplitRevisionDbName(currentDb) + p.mu.RLock() - showBranches, _ := dsess.GetBooleanSystemVar(ctx, dsess.ShowBranchDatabases) all = make([]sql.Database, 0, len(p.databases)) for _, db := range p.databases { + base, _ := dsess.SplitRevisionDbName(db.Name()) + + // If there's a revision database in use, swap that one in for its base db, but keep the same name + if currRev != "" && strings.ToLower(currBase) == strings.ToLower(base) { + var err error + var ok bool + db, ok, err = p.databaseForRevision(ctx, currentDb, currBase) + if err != nil || !ok { + // TODO: this interface is wrong, needs to return errors + ctx.GetLogger().Warnf("error fetching revision databases: %s", err.Error()) + } + } + all = append(all, db) if showBranches { From a2a69f3f5e28cebc9a815d8e68557f5fc44ec4b1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 11:15:43 -0700 Subject: [PATCH 121/167] Fixed NPE when a database is deleted --- go/libraries/doltcore/sqle/database_provider.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 069b522980..51b40e3880 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -267,12 +267,12 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database // If there's a revision database in use, swap that one in for its base db, but keep the same name if currRev != "" && strings.ToLower(currBase) == strings.ToLower(base) { - var err error - var ok bool - db, ok, err = p.databaseForRevision(ctx, currentDb, currBase) + rdb, ok, err := p.databaseForRevision(ctx, currentDb, currBase) if err != nil || !ok { // TODO: this interface is wrong, needs to return errors ctx.GetLogger().Warnf("error fetching revision databases: %s", err.Error()) + } else { + db = rdb } } From 81ab90b6a78a74202225333743154af625a9272f Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 12:27:02 -0700 Subject: [PATCH 122/167] Branch tests for foreign key creation / enforcement --- .../doltcore/sqle/database_provider.go | 4 +- .../sqle/enginetest/dolt_branch_queries.go | 164 ++++++++++++++++++ .../sqle/enginetest/dolt_engine_test.go | 58 +++++++ .../enginetest/dolt_transaction_queries.go | 2 +- 4 files changed, 226 insertions(+), 2 deletions(-) create mode 100755 go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 51b40e3880..d4c8a52e4e 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -171,7 +171,9 @@ func (p DoltDatabaseProvider) FileSystemForDatabase(dbname string) (filesys.File p.mu.Lock() defer p.mu.Unlock() - dbLocation, ok := p.dbLocations[dbname] + baseName, _ := dsess.SplitRevisionDbName(dbname) + + dbLocation, ok := p.dbLocations[strings.ToLower(baseName)] if !ok { return nil, sql.ErrDatabaseNotFound.New(dbname) } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go new file mode 100755 index 0000000000..cb504ff092 --- /dev/null +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -0,0 +1,164 @@ +// Copyright 2022 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package enginetest + +import ( + "github.com/dolthub/go-mysql-server/enginetest/queries" + "github.com/dolthub/go-mysql-server/sql" + "github.com/dolthub/go-mysql-server/sql/types" +) + +var ForeignKeyBranchTests = []queries.ScriptTest{ + { + Name: "create fk on branch", + SetUpScript: []string { + "call dolt_branch('b1')", + "use mydb/b1", + "ALTER TABLE child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/b1", + SkipResultsCheck: false, + }, + { + Query: "SHOW CREATE TABLE child;", + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`),\n" + + " KEY `v1` (`v1`),\n" + + " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into child values (1, 1, 1)", + ExpectedErr: sql.ErrForeignKeyChildViolation, + }, + { + Query: "use mydb/main", + SkipResultsCheck: false, + }, + { + Query: "SHOW CREATE TABLE child;", + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into child values (1, 1, 1)", + Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, + }, + { + Query: "insert into `mydb/b1`.child values (1, 1, 1)", + ExpectedErr: sql.ErrForeignKeyChildViolation, + }, + }, + }, + { + Name: "create fk with branch checkout", + SetUpScript: []string { + "call dolt_branch('b1')", + "call dolt_checkout('b1')", + "ALTER TABLE child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "call dolt_checkout('b1')", + SkipResultsCheck: true, + }, + { + Query: "SHOW CREATE TABLE child;", + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`),\n" + + " KEY `v1` (`v1`),\n" + + " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into child values (1, 1, 1)", + ExpectedErr: sql.ErrForeignKeyChildViolation, + }, + { + Query: "call dolt_checkout('main')", + SkipResultsCheck: true, + }, + { + Query: "SHOW CREATE TABLE child;", + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into child values (1, 1, 1)", + Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, + }, + }, + }, + { + Name: "create fk on branch not being used", + SetUpScript: []string { + "call dolt_branch('b1')", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "ALTER TABLE `mydb/b1`.child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", + Skip: true, // Incorrectly flagged as a cross-DB foreign key relation + }, + { + Query: "SHOW CREATE TABLE `mydb/b1`.child;", + Skip: true, + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`),\n" + + " KEY `v1` (`v1`),\n" + + " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into `mydb/b1`.child values (1, 1, 1)", + Skip: true, + ExpectedErr: sql.ErrForeignKeyChildViolation, + }, + { + Query: "SHOW CREATE TABLE child;", + Skip: true, + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into child values (1, 1, 1)", + Skip: true, + Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, + }, + }, + }, +} diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 6b0c09fe82..ec9005c2d3 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -865,6 +865,64 @@ func TestForeignKeys(t *testing.T) { enginetest.TestForeignKeys(t, h) } +func TestForeignKeyBranches(t *testing.T) { + setupPrefix := []string { + "call dolt_branch('b1')", + "use mydb/b1", + } + assertionsPrefix := []queries.ScriptTestAssertion { + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + } + for _, script := range queries.ForeignKeyTests { + // New harness for every script because we create branches + h := newDoltHarness(t) + h.Setup(setup.MydbData, setup.Parent_childData) + modifiedScript := script + modifiedScript.SetUpScript = append(setupPrefix, modifiedScript.SetUpScript...) + modifiedScript.Assertions = append(assertionsPrefix, modifiedScript.Assertions...) + enginetest.TestScript(t, h, modifiedScript) + } + + for _, script := range ForeignKeyBranchTests { + // New harness for every script because we create branches + h := newDoltHarness(t) + h.Setup(setup.MydbData, setup.Parent_childData) + enginetest.TestScript(t, h, script) + } +} + +func TestForeignKeyBranchesPrepared(t *testing.T) { + setupPrefix := []string { + "call dolt_branch('b1')", + "use mydb/b1", + } + assertionsPrefix := []queries.ScriptTestAssertion { + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + } + for _, script := range queries.ForeignKeyTests { + // New harness for every script because we create branches + h := newDoltHarness(t) + h.Setup(setup.MydbData, setup.Parent_childData) + modifiedScript := script + modifiedScript.SetUpScript = append(setupPrefix, modifiedScript.SetUpScript...) + modifiedScript.Assertions = append(assertionsPrefix, modifiedScript.Assertions...) + enginetest.TestScriptPrepared(t, h, modifiedScript) + } + + for _, script := range ForeignKeyBranchTests { + // New harness for every script because we create branches + h := newDoltHarness(t) + h.Setup(setup.MydbData, setup.Parent_childData) + enginetest.TestScriptPrepared(t, h, script) + } +} + func TestCreateCheckConstraints(t *testing.T) { h := newDoltHarness(t) defer h.Close() diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 84da6aff04..778e80ef74 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2926,4 +2926,4 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, -} +} \ No newline at end of file From 53496494334b96c720968c5f31d8ed7e900702bb Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 12:27:34 -0700 Subject: [PATCH 123/167] Formatting --- .../sqle/enginetest/dolt_branch_queries.go | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index cb504ff092..f5c2a26cfa 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -22,8 +22,8 @@ import ( var ForeignKeyBranchTests = []queries.ScriptTest{ { - Name: "create fk on branch", - SetUpScript: []string { + Name: "create fk on branch", + SetUpScript: []string{ "call dolt_branch('b1')", "use mydb/b1", "ALTER TABLE child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", @@ -34,7 +34,7 @@ var ForeignKeyBranchTests = []queries.ScriptTest{ SkipResultsCheck: false, }, { - Query: "SHOW CREATE TABLE child;", + Query: "SHOW CREATE TABLE child;", Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + " `id` int NOT NULL,\n" + " `v1` int,\n" + @@ -45,7 +45,7 @@ var ForeignKeyBranchTests = []queries.ScriptTest{ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into child values (1, 1, 1)", + Query: "insert into child values (1, 1, 1)", ExpectedErr: sql.ErrForeignKeyChildViolation, }, { @@ -53,110 +53,110 @@ var ForeignKeyBranchTests = []queries.ScriptTest{ SkipResultsCheck: false, }, { - Query: "SHOW CREATE TABLE child;", + Query: "SHOW CREATE TABLE child;", Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + - " `id` int NOT NULL,\n" + - " `v1` int,\n" + - " `v2` int,\n" + - " PRIMARY KEY (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into child values (1, 1, 1)", + Query: "insert into child values (1, 1, 1)", Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, }, { - Query: "insert into `mydb/b1`.child values (1, 1, 1)", + Query: "insert into `mydb/b1`.child values (1, 1, 1)", ExpectedErr: sql.ErrForeignKeyChildViolation, }, }, }, { - Name: "create fk with branch checkout", - SetUpScript: []string { + Name: "create fk with branch checkout", + SetUpScript: []string{ "call dolt_branch('b1')", "call dolt_checkout('b1')", "ALTER TABLE child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "call dolt_checkout('b1')", + Query: "call dolt_checkout('b1')", SkipResultsCheck: true, }, { - Query: "SHOW CREATE TABLE child;", + Query: "SHOW CREATE TABLE child;", Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + - " `id` int NOT NULL,\n" + - " `v1` int,\n" + - " `v2` int,\n" + - " PRIMARY KEY (`id`),\n" + - " KEY `v1` (`v1`),\n" + - " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`),\n" + + " KEY `v1` (`v1`),\n" + + " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into child values (1, 1, 1)", + Query: "insert into child values (1, 1, 1)", ExpectedErr: sql.ErrForeignKeyChildViolation, }, { - Query: "call dolt_checkout('main')", + Query: "call dolt_checkout('main')", SkipResultsCheck: true, }, { - Query: "SHOW CREATE TABLE child;", + Query: "SHOW CREATE TABLE child;", Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + - " `id` int NOT NULL,\n" + - " `v1` int,\n" + - " `v2` int,\n" + - " PRIMARY KEY (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into child values (1, 1, 1)", + Query: "insert into child values (1, 1, 1)", Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, }, }, }, { - Name: "create fk on branch not being used", - SetUpScript: []string { + Name: "create fk on branch not being used", + SetUpScript: []string{ "call dolt_branch('b1')", }, Assertions: []queries.ScriptTestAssertion{ { - Query: "ALTER TABLE `mydb/b1`.child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", - Skip: true, // Incorrectly flagged as a cross-DB foreign key relation + Query: "ALTER TABLE `mydb/b1`.child ADD CONSTRAINT fk_named FOREIGN KEY (v1) REFERENCES parent(v1);", + Skip: true, // Incorrectly flagged as a cross-DB foreign key relation }, { - Query: "SHOW CREATE TABLE `mydb/b1`.child;", - Skip: true, + Query: "SHOW CREATE TABLE `mydb/b1`.child;", + Skip: true, Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + - " `id` int NOT NULL,\n" + - " `v1` int,\n" + - " `v2` int,\n" + - " PRIMARY KEY (`id`),\n" + - " KEY `v1` (`v1`),\n" + - " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`),\n" + + " KEY `v1` (`v1`),\n" + + " CONSTRAINT `fk_named` FOREIGN KEY (`v1`) REFERENCES `parent` (`v1`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into `mydb/b1`.child values (1, 1, 1)", - Skip: true, + Query: "insert into `mydb/b1`.child values (1, 1, 1)", + Skip: true, ExpectedErr: sql.ErrForeignKeyChildViolation, }, { - Query: "SHOW CREATE TABLE child;", - Skip: true, + Query: "SHOW CREATE TABLE child;", + Skip: true, Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n" + - " `id` int NOT NULL,\n" + - " `v1` int,\n" + - " `v2` int,\n" + - " PRIMARY KEY (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `id` int NOT NULL,\n" + + " `v1` int,\n" + + " `v2` int,\n" + + " PRIMARY KEY (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into child values (1, 1, 1)", - Skip: true, + Query: "insert into child values (1, 1, 1)", + Skip: true, Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, }, }, From db2a7fc21117fb30d26cfc3563f9a3ffe51cca44 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 13:30:00 -0700 Subject: [PATCH 124/167] Tests of views on branches --- .../sqle/enginetest/dolt_branch_queries.go | 64 ++++++++++++++++++- .../sqle/enginetest/dolt_engine_test.go | 20 ++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index f5c2a26cfa..0e3fe81e15 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -31,7 +31,7 @@ var ForeignKeyBranchTests = []queries.ScriptTest{ Assertions: []queries.ScriptTestAssertion{ { Query: "use mydb/b1", - SkipResultsCheck: false, + SkipResultsCheck: true, }, { Query: "SHOW CREATE TABLE child;", @@ -50,7 +50,7 @@ var ForeignKeyBranchTests = []queries.ScriptTest{ }, { Query: "use mydb/main", - SkipResultsCheck: false, + SkipResultsCheck: true, }, { Query: "SHOW CREATE TABLE child;", @@ -162,3 +162,63 @@ var ForeignKeyBranchTests = []queries.ScriptTest{ }, }, } + +var ViewBranchTests = []queries.ScriptTest{ + { + Name: "create view on branch", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "use mydb/b1", + "create view v1 as select * from t1 where a > 2", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + { + Query: "select * from v1", + Expected: []sql.Row{{3, 3}}, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "select * from v1", + ExpectedErr: sql.ErrTableNotFound, + }, + }, + }, + { + Name: "create view with no branch selected", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "create view `mydb/b1`.v1 as select * from t1 where a > 2", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + { + Query: "select * from v1", + Expected: []sql.Row{{3, 3}}, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "select * from v1", + ExpectedErr: sql.ErrTableNotFound, + }, + }, + }, +} \ No newline at end of file diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index ec9005c2d3..fe0b7483ae 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -965,6 +965,26 @@ func TestViews(t *testing.T) { enginetest.TestViews(t, h) } +func TestBranchViews(t *testing.T) { + for _, script := range ViewBranchTests { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScript(t, h, script) + }() + } +} + +func TestBranchViewsPrepared(t *testing.T) { + for _, script := range ViewBranchTests { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScriptPrepared(t, h, script) + }() + } +} + func TestVersionedViews(t *testing.T) { h := newDoltHarness(t) defer h.Close() From 3c3182c9e1980498278b0bfd0ef4f45cc0cb5237 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 14:53:22 -0700 Subject: [PATCH 125/167] DDL tests --- .../sqle/enginetest/dolt_branch_queries.go | 282 +++++++++++++++++- .../sqle/enginetest/dolt_engine_test.go | 20 ++ 2 files changed, 300 insertions(+), 2 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index 0e3fe81e15..26b784818d 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -191,10 +191,14 @@ var ViewBranchTests = []queries.ScriptTest{ Query: "select * from v1", ExpectedErr: sql.ErrTableNotFound, }, + { + Query: "select * from `mydb/b1`.v1", + Expected: []sql.Row{{3, 3}}, + }, }, }, { - Name: "create view with no branch selected", + Name: "create view on different branch", SetUpScript: []string{ "create table t1 (a int primary key, b int)", "insert into t1 values (1, 1), (2, 2), (3, 3)", @@ -219,6 +223,280 @@ var ViewBranchTests = []queries.ScriptTest{ Query: "select * from v1", ExpectedErr: sql.ErrTableNotFound, }, + { + Query: "select * from `mydb/b1`.v1", + Expected: []sql.Row{{3, 3}}, + }, }, }, -} \ No newline at end of file +} + +var DdlBranchTests = []queries.ScriptTest{ + { + Name: "create table on branch", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "use mydb/b1", + "create table t2 (a int primary key, b int)", + "insert into t2 values (4, 4)", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + { + Query: "select * from t2", + Expected: []sql.Row{{4, 4}}, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "select * from t2", + ExpectedErr: sql.ErrTableNotFound, + }, + { + Query: "select * from `mydb/b1`.t2", + Expected: []sql.Row{{4, 4}}, + }, + }, + }, + { + Name: "create table on different branch", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "create table `mydb/b1`.t2 (a int primary key, b int)", + "insert into `mydb/b1`.t2 values (4,4)", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + { + Query: "select * from t2", + Expected: []sql.Row{{4, 4}}, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "select * from t2", + ExpectedErr: sql.ErrTableNotFound, + }, + { + Query: "select * from `mydb/b1`.t2", + Expected: []sql.Row{{4, 4}}, + }, + }, + }, + { + Name: "create table on different branch, autocommit off", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "set autocommit = off", + "create table `mydb/b1`.t2 (a int primary key, b int)", + "insert into `mydb/b1`.t2 values (4,4)", + "commit", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/b1", + SkipResultsCheck: true, + }, + { + Query: "select * from t2", + Expected: []sql.Row{{4, 4}}, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "select * from t2", + ExpectedErr: sql.ErrTableNotFound, + }, + { + Query: "select * from `mydb/b1`.t2", + Expected: []sql.Row{{4, 4}}, + }, + }, + }, + { + Name: "alter table on different branch, add column", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "alter table `mydb/b1`.t1 add column c int", + Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, + }, + { + Query: "select * from `mydb/b1`.t1", + Expected: []sql.Row{{1, 1, nil}, {2, 2, nil}, {3, 3, nil}}, + }, + { + Query: "select * from t1", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + }, + }, + }, + { + Name: "alter table on different branch, drop column", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "alter table `mydb/b1`.t1 drop column b", + Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, + }, + { + Query: "select * from `mydb/b1`.t1", + Expected: []sql.Row{{1}, {2}, {3}}, + }, + { + Query: "select * from t1", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + }, + }, + }, + { + Name: "alter table on different branch, modify column", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "alter table `mydb/b1`.t1 modify column b varchar(1) first", + Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, + }, + { + Query: "select * from `mydb/b1`.t1", + Expected: []sql.Row{{"1", 1}, {"2", 2}, {"3", 3}}, + }, + { + Query: "select * from t1", + Expected: []sql.Row{{1, 1}, {2, 2}, {3, 3}}, + }, + }, + }, + { + Name: "alter table on different branch, create and drop index", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "create index idx on `mydb/b1`.t1 (b)", + Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, + }, + { + Query: "show create table `mydb/b1`.t1", + Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`),\n" + + " KEY `idx` (`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "show create table t1", + Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "alter table `mydb/b1`.t1 drop index idx", + Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, + }, + { + Query: "show create table `mydb/b1`.t1", + Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + }, + }, + { + Name: "alter table on different branch, add and drop constraint", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "alter table `mydb/b1`.t1 add constraint chk1 check (b < 4)", + Expected: []sql.Row{}, + }, + { + Query: "show create table `mydb/b1`.t1", + Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`),\n" + + " CONSTRAINT `chk1` CHECK ((`b` < 4))\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into `mydb/b1`.t1 values (4, 4)", + ExpectedErr: sql.ErrCheckConstraintViolated, + }, + { + Query: "show create table t1", + Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + { + Query: "insert into t1 values (4, 4)", + Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, + }, + { + Query: "alter table `mydb/b1`.t1 drop constraint chk1", + Expected: []sql.Row{}, + }, + { + Query: "show create table `mydb/b1`.t1", + Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + }, + }, +} diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index fe0b7483ae..4a99405139 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -718,6 +718,26 @@ func TestCreateTable(t *testing.T) { enginetest.TestCreateTable(t, h) } +func TestBranchDdl(t *testing.T) { + for _, script := range DdlBranchTests { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScript(t, h, script) + }() + } +} + +func TestBranchDdlPrepared(t *testing.T) { + for _, script := range DdlBranchTests { + func() { + h := newDoltHarness(t) + defer h.Close() + enginetest.TestScriptPrepared(t, h, script) + }() + } +} + func TestPkOrdinalsDDL(t *testing.T) { h := newDoltHarness(t) defer h.Close() From 9edd0cca6e1e99a41890fa84ace033c8cd085980 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 15:08:01 -0700 Subject: [PATCH 126/167] Added skips for bug in view creation --- go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index 26b784818d..6d88df2944 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -214,6 +214,7 @@ var ViewBranchTests = []queries.ScriptTest{ { Query: "select * from v1", Expected: []sql.Row{{3, 3}}, + Skip: true, // https://github.com/dolthub/dolt/issues/6078 }, { Query: "use mydb/main", @@ -222,10 +223,12 @@ var ViewBranchTests = []queries.ScriptTest{ { Query: "select * from v1", ExpectedErr: sql.ErrTableNotFound, + Skip: true, // https://github.com/dolthub/dolt/issues/6078 }, { Query: "select * from `mydb/b1`.v1", Expected: []sql.Row{{3, 3}}, + Skip: true, // https://github.com/dolthub/dolt/issues/6078 }, }, }, From 978d11d9e8c581581719919ef7afe1b887d35b51 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 15:22:04 -0700 Subject: [PATCH 127/167] Tests of query planning on branch dbs --- .../sqle/enginetest/dolt_branch_queries.go | 95 +++++++++++++++++++ .../sqle/enginetest/dolt_engine_test.go | 10 ++ 2 files changed, 105 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index 6d88df2944..842236453a 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -503,3 +503,98 @@ var DdlBranchTests = []queries.ScriptTest{ }, }, } + +var BranchPlanTests = []queries.ScriptTest{ + { + Name: "use index on branch database", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "use mydb/b1", + "create index idx on t1 (b)", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "explain select * from t1 where b = 1", + Expected: []sql.Row{ + {"IndexedTableAccess(t1)"}, + {" ├─ index: [t1.b]"}, + {" ├─ filters: [{[1, 1]}]"}, + {" └─ columns: [a b]"}, + }, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "explain select * from `mydb/b1`.t1 where b = 1", + Expected: []sql.Row{ + {"IndexedTableAccess(t1)"}, + {" ├─ index: [t1.b]"}, + {" ├─ filters: [{[1, 1]}]"}, + {" └─ columns: [a b]"}, + }, + }, + }, + }, + { + Name: "use index on branch database join", + SetUpScript: []string{ + "create table t1 (a int primary key, b int)", + "insert into t1 values (1, 1), (2, 2), (3, 3)", + "call dolt_commit('-Am', 'first commit')", + "call dolt_branch('b1')", + "use mydb/b1", + "create index idx on t1 (b)", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "explain select * from t1 t1a join t1 t1b on t1a.b = t1b.b order by 1", + Expected: []sql.Row{ + {"Sort(t1a.a ASC)"}, + {" └─ Project"}, + {" ├─ columns: [t1a.a, t1a.b, t1b.a, t1b.b]"}, + {" └─ MergeJoin"}, + {" ├─ cmp: (t1b.b = t1a.b)"}, + {" ├─ TableAlias(t1b)"}, + {" │ └─ IndexedTableAccess(t1)"}, + {" │ ├─ index: [t1.b]"}, + {" │ ├─ filters: [{[NULL, ∞)}]"}, + {" │ └─ columns: [a b]"}, + {" └─ TableAlias(t1a)"}, + {" └─ IndexedTableAccess(t1)"}, + {" ├─ index: [t1.b]"}, + {" ├─ filters: [{[NULL, ∞)}]"}, + {" └─ columns: [a b]"}, + }, + }, + { + Query: "use mydb/main", + SkipResultsCheck: true, + }, + { + Query: "explain select * from `mydb/b1`.t1 t1a join `mydb/b1`.t1 t1b on t1a.b = t1b.b order by 1", + Expected: []sql.Row{ + {"Sort(t1a.a ASC)"}, + {" └─ Project"}, + {" ├─ columns: [t1a.a, t1a.b, t1b.a, t1b.b]"}, + {" └─ MergeJoin"}, + {" ├─ cmp: (t1b.b = t1a.b)"}, + {" ├─ TableAlias(t1b)"}, + {" │ └─ IndexedTableAccess(t1)"}, + {" │ ├─ index: [t1.b]"}, + {" │ ├─ filters: [{[NULL, ∞)}]"}, + {" │ └─ columns: [a b]"}, + {" └─ TableAlias(t1a)"}, + {" └─ IndexedTableAccess(t1)"}, + {" ├─ index: [t1.b]"}, + {" ├─ filters: [{[NULL, ∞)}]"}, + {" └─ columns: [a b]"}, + }, + }, + }, + }, +} diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 4a99405139..850dbbcb85 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -364,6 +364,16 @@ func TestDoltDiffQueryPlans(t *testing.T) { } } +func TestBranchPlans(t *testing.T) { + for _, script := range BranchPlanTests { + func() { + harness := newDoltHarness(t) + defer harness.Close() + enginetest.TestScript(t, harness, script) + }() + } +} + func TestQueryErrors(t *testing.T) { h := newDoltHarness(t) defer h.Close() From e1bd0693a984a843eae5518c89cf1cdb1b3a0ded Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 15:45:44 -0700 Subject: [PATCH 128/167] More plan tests --- .../sqle/enginetest/dolt_branch_queries.go | 32 +++++++++++++++++++ .../sqle/enginetest/dolt_engine_test.go | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index 842236453a..8c7b3aac2c 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -571,10 +571,42 @@ var BranchPlanTests = []queries.ScriptTest{ {" └─ columns: [a b]"}, }, }, + { + Query: "explain select * from `mydb/main`.t1 t1a join `mydb/main`.t1 t1b on t1a.b = t1b.b order by 1", + Expected: []sql.Row{ + {"Sort(t1a.a ASC)"}, + {" └─ InnerJoin"}, + {" ├─ (t1a.b = t1b.b)"}, + {" ├─ TableAlias(t1a)"}, + {" │ └─ Table"}, + {" │ ├─ name: t1"}, + {" │ └─ columns: [a b]"}, + {" └─ TableAlias(t1b)"}, + {" └─ Table"}, + {" ├─ name: t1"}, + {" └─ columns: [a b]"}, + }, + }, { Query: "use mydb/main", SkipResultsCheck: true, }, + { + Query: "explain select * from t1 t1a join t1 t1b on t1a.b = t1b.b order by 1", + Expected: []sql.Row{ + {"Sort(t1a.a ASC)"}, + {" └─ InnerJoin"}, + {" ├─ (t1a.b = t1b.b)"}, + {" ├─ TableAlias(t1a)"}, + {" │ └─ Table"}, + {" │ ├─ name: t1"}, + {" │ └─ columns: [a b]"}, + {" └─ TableAlias(t1b)"}, + {" └─ Table"}, + {" ├─ name: t1"}, + {" └─ columns: [a b]"}, + }, + }, { Query: "explain select * from `mydb/b1`.t1 t1a join `mydb/b1`.t1 t1b on t1a.b = t1b.b order by 1", Expected: []sql.Row{ diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 850dbbcb85..90b6ab2b99 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -367,7 +367,7 @@ func TestDoltDiffQueryPlans(t *testing.T) { func TestBranchPlans(t *testing.T) { for _, script := range BranchPlanTests { func() { - harness := newDoltHarness(t) + harness := newDoltHarness(t).WithParallelism(1) defer harness.Close() enginetest.TestScript(t, harness, script) }() From 3b207b324c1b6155bf0524ba71cb6f4186f742cd Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 16:35:10 -0700 Subject: [PATCH 129/167] Spot check tests for branch control permissions --- .../sqle/enginetest/branch_control_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go index 37c65438fb..af79354b48 100644 --- a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go +++ b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go @@ -80,6 +80,11 @@ var BranchControlBlockTests = []BranchControlBlockTest{ Query: "INSERT INTO test VALUES (2, 2);", ExpectedErr: branch_control.ErrIncorrectPermissions, }, + { + Name: "INSERT on branch db", + Query: "INSERT INTO `mydb/other`.test VALUES (2, 2);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, { Name: "REPLACE", Query: "REPLACE INTO test VALUES (2, 2);", @@ -90,11 +95,21 @@ var BranchControlBlockTests = []BranchControlBlockTest{ Query: "UPDATE test SET pk = 2;", ExpectedErr: branch_control.ErrIncorrectPermissions, }, + { + Name: "UPDATE on branch db", + Query: "UPDATE `mydb/other`.test SET pk = 2;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, { Name: "DELETE", Query: "DELETE FROM test WHERE pk >= 0;", ExpectedErr: branch_control.ErrIncorrectPermissions, }, + { + Name: "DELETE from branch table", + Query: "DELETE FROM `mydb/other`.test WHERE pk >= 0;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, { Name: "TRUNCATE", Query: "TRUNCATE TABLE test;", @@ -1211,9 +1226,11 @@ func TestBranchControlBlocks(t *testing.T) { Address: "localhost", }) enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) + addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write'), ('%', 'other', 'testuser', 'localhost', 'write');" addUserQueryResults := []sql.Row{{types.NewOkResult(2)}} enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) + sch, iter, err := engine.Query(userCtx, test.Query) if err == nil { _, err = sql.RowIterToRows(userCtx, sch, iter) From fa5c8477f950518d7c065923e4b5bec69e8daac4 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 16:55:40 -0700 Subject: [PATCH 130/167] Fixed branch control permissions, but introduce import cycle --- .../doltcore/branch_control/branch_control.go | 36 ++++++++++ go/libraries/doltcore/sqle/database.go | 18 ++--- .../sqle/enginetest/branch_control_test.go | 69 +++++++++++++++++-- go/libraries/doltcore/sqle/tables.go | 36 +++++----- 4 files changed, 126 insertions(+), 33 deletions(-) diff --git a/go/libraries/doltcore/branch_control/branch_control.go b/go/libraries/doltcore/branch_control/branch_control.go index 6e6238f02d..3acd1fbe9d 100644 --- a/go/libraries/doltcore/branch_control/branch_control.go +++ b/go/libraries/doltcore/branch_control/branch_control.go @@ -20,6 +20,7 @@ import ( "fmt" "os" + "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" flatbuffers "github.com/dolthub/flatbuffers/v23/go" "github.com/dolthub/go-mysql-server/sql" "gopkg.in/src-d/go-errors.v1" @@ -200,6 +201,41 @@ func CheckAccess(ctx context.Context, flags Permissions) error { return ErrIncorrectPermissions.New(user, host, branch) } +func CheckAccessForDb(ctx context.Context, db dsess.SqlDatabase, flags Permissions) error { + branchAwareSession := GetBranchAwareSession(ctx) + // A nil session means we're not in the SQL context, so we allow all operations + if branchAwareSession == nil { + return nil + } + + controller := branchAwareSession.GetController() + // Any context that has a non-nil session should always have a non-nil controller, so this is an error + if controller == nil { + return ErrMissingController.New() + } + + controller.Access.RWMutex.RLock() + defer controller.Access.RWMutex.RUnlock() + + user := branchAwareSession.GetUser() + host := branchAwareSession.GetHost() + + if db.RevisionType() != dsess.RevisionTypeBranch { + // not a branch db, no check necessary + return nil + } + + dbName, branch := dsess.SplitRevisionDbName(db.RevisionQualifiedName()) + + // Get the permissions for the branch, user, and host combination + _, perms := controller.Access.Match(dbName, branch, user, host) + // If either the flags match or the user is an admin for this branch, then we allow access + if (perms&flags == flags) || (perms&Permissions_Admin == Permissions_Admin) { + return nil + } + return ErrIncorrectPermissions.New(user, host, branch) +} + // CanCreateBranch returns whether the given context can create a branch with the given name. In general, SQL statements // will almost always return a *sql.Context, so any checks from the SQL path will be able to validate a branch's name. // However, not all CLI commands use *sql.Context, and therefore will not have any user associated with the context. In diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 1914edf0aa..aee645faec 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -711,7 +711,7 @@ func (db Database) GetHeadRoot(ctx *sql.Context) (*doltdb.RootValue, error) { // DropTable drops the table with the name given. // The planner returns the correct case sensitive name in tableName func (db Database) DropTable(ctx *sql.Context, tableName string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if doltdb.IsNonAlterableSystemTable(tableName) { @@ -818,7 +818,7 @@ func (db Database) removeTableFromAutoIncrementTracker( // CreateTable creates a table with the name and schema given. func (db Database) CreateTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, collation sql.CollationID) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if strings.ToLower(tableName) == doltdb.DocTableName { @@ -839,7 +839,7 @@ func (db Database) CreateTable(ctx *sql.Context, tableName string, sch sql.Prima // CreateIndexedTable creates a table with the name and schema given. func (db Database) CreateIndexedTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, idxDef sql.IndexDef, collation sql.CollationID) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if strings.ToLower(tableName) == doltdb.DocTableName { @@ -1003,7 +1003,7 @@ func (db Database) CreateTemporaryTable(ctx *sql.Context, tableName string, pkSc // RenameTable implements sql.TableRenamer func (db Database) RenameTable(ctx *sql.Context, oldName, newName string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } root, err := db.GetRoot(ctx) @@ -1317,7 +1317,7 @@ func (db Database) GetStoredProcedures(ctx *sql.Context) ([]sql.StoredProcedureD // SaveStoredProcedure implements sql.StoredProcedureDatabase. func (db Database) SaveStoredProcedure(ctx *sql.Context, spd sql.StoredProcedureDetails) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } return DoltProceduresAddProcedure(ctx, db, spd) @@ -1325,14 +1325,14 @@ func (db Database) SaveStoredProcedure(ctx *sql.Context, spd sql.StoredProcedure // DropStoredProcedure implements sql.StoredProcedureDatabase. func (db Database) DropStoredProcedure(ctx *sql.Context, name string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } return DoltProceduresDropProcedure(ctx, db, name) } func (db Database) addFragToSchemasTable(ctx *sql.Context, fragType, name, definition string, created time.Time, existingErr error) (err error) { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } tbl, err := getOrCreateDoltSchemasTable(ctx, db) @@ -1369,7 +1369,7 @@ func (db Database) addFragToSchemasTable(ctx *sql.Context, fragType, name, defin } func (db Database) dropFragFromSchemasTable(ctx *sql.Context, fragType, name string, missingErr error) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } @@ -1458,7 +1458,7 @@ func (db Database) GetCollation(ctx *sql.Context) sql.CollationID { // SetCollation implements the interface sql.CollatedDatabase. func (db Database) SetCollation(ctx *sql.Context, collation sql.CollationID) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if collation == sql.Collation_Unspecified { diff --git a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go index af79354b48..aae97f1843 100644 --- a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go +++ b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go @@ -1201,7 +1201,59 @@ func TestBranchControl(t *testing.T) { } func TestBranchControlBlocks(t *testing.T) { - for _, test := range BranchControlBlockTests { + // for _, test := range BranchControlBlockTests { + // harness := newDoltHarness(t) + // defer harness.Close() + // t.Run(test.Name, func(t *testing.T) { + // engine, err := harness.NewEngine(t) + // require.NoError(t, err) + // defer engine.Close() + // + // rootCtx := enginetest.NewContext(harness) + // rootCtx.NewCtxWithClient(sql.Client{ + // User: "root", + // Address: "localhost", + // }) + // engine.Analyzer.Catalog.MySQLDb.AddRootAccount() + // engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) + // + // for _, statement := range append(TestUserSetUpScripts, test.SetUpScript...) { + // enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) + // } + // + // userCtx := enginetest.NewContextWithClient(harness, sql.Client{ + // User: "testuser", + // Address: "localhost", + // }) + // enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) + // + // addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write'), ('%', 'other', 'testuser', 'localhost', 'write');" + // addUserQueryResults := []sql.Row{{types.NewOkResult(2)}} + // enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) + // + // sch, iter, err := engine.Query(userCtx, test.Query) + // if err == nil { + // _, err = sql.RowIterToRows(userCtx, sch, iter) + // } + // assert.NoError(t, err) + // }) + // } + + // These tests are run with permission on main but not other + var branchRevisionTests = []BranchControlBlockTest{ + { + Name: "INSERT on branch db, permissions on main", + Query: "INSERT INTO `mydb/other`.test VALUES (2, 2);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "DELETE on branch db, permissions on main", + Query: "DELETE from `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + } + + for _, test := range branchRevisionTests { harness := newDoltHarness(t) defer harness.Close() t.Run(test.Name, func(t *testing.T) { @@ -1216,21 +1268,25 @@ func TestBranchControlBlocks(t *testing.T) { }) engine.Analyzer.Catalog.MySQLDb.AddRootAccount() engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) - + for _, statement := range append(TestUserSetUpScripts, test.SetUpScript...) { enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) } + // addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write');" + // addUserQueryResults := []sql.Row{{types.NewOkResult(1)}} + // enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) + userCtx := enginetest.NewContextWithClient(harness, sql.Client{ User: "testuser", Address: "localhost", }) enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) - - addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write'), ('%', 'other', 'testuser', 'localhost', 'write');" - addUserQueryResults := []sql.Row{{types.NewOkResult(2)}} + + addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'other', 'testuser', 'localhost', 'write');" + addUserQueryResults := []sql.Row{{types.NewOkResult(1)}} enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) - + sch, iter, err := engine.Query(userCtx, test.Query) if err == nil { _, err = sql.RowIterToRows(userCtx, sch, iter) @@ -1238,4 +1294,5 @@ func TestBranchControlBlocks(t *testing.T) { assert.NoError(t, err) }) } + } diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 0b04a552ef..a810d6b5c2 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -497,7 +497,7 @@ func (t *WritableDoltTable) WithProjections(colNames []string) sql.Table { // Inserter implements sql.InsertableTable func (t *WritableDoltTable) Inserter(ctx *sql.Context) sql.RowInserter { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -539,7 +539,7 @@ func (t *WritableDoltTable) getTableEditor(ctx *sql.Context) (ed writer.TableWri // Deleter implements sql.DeletableTable func (t *WritableDoltTable) Deleter(ctx *sql.Context) sql.RowDeleter { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -551,7 +551,7 @@ func (t *WritableDoltTable) Deleter(ctx *sql.Context) sql.RowDeleter { // Replacer implements sql.ReplaceableTable func (t *WritableDoltTable) Replacer(ctx *sql.Context) sql.RowReplacer { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -563,7 +563,7 @@ func (t *WritableDoltTable) Replacer(ctx *sql.Context) sql.RowReplacer { // Truncate implements sql.TruncateableTable func (t *WritableDoltTable) Truncate(ctx *sql.Context) (int, error) { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return 0, err } table, err := t.DoltTable.DoltTable(ctx) @@ -700,7 +700,7 @@ func copyConstraintViolationsAndConflicts(ctx context.Context, from, to *doltdb. // Updater implements sql.UpdatableTable func (t *WritableDoltTable) Updater(ctx *sql.Context) sql.RowUpdater { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -712,7 +712,7 @@ func (t *WritableDoltTable) Updater(ctx *sql.Context) sql.RowUpdater { // AutoIncrementSetter implements sql.AutoIncrementTable func (t *WritableDoltTable) AutoIncrementSetter(ctx *sql.Context) sql.AutoIncrementSetter { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -1099,7 +1099,7 @@ func (t *AlterableDoltTable) WithProjections(colNames []string) sql.Table { // AddColumn implements sql.AlterableTable func (t *AlterableDoltTable) AddColumn(ctx *sql.Context, column *sql.Column, order *sql.ColumnOrder) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -1236,7 +1236,7 @@ func (t *AlterableDoltTable) RewriteInserter( newColumn *sql.Column, idxCols []sql.IndexColumn, ) (sql.RowInserter, error) { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return nil, err } err := validateSchemaChange(t.Name(), oldSchema, newSchema, oldColumn, newColumn, idxCols) @@ -1613,7 +1613,7 @@ func (t *AlterableDoltTable) dropColumnData(ctx *sql.Context, updatedTable *dolt // ModifyColumn implements sql.AlterableTable. ModifyColumn operations are only used for operations that change only // the schema of a table, not the data. For those operations, |RewriteInserter| is used. func (t *AlterableDoltTable) ModifyColumn(ctx *sql.Context, columnName string, column *sql.Column, order *sql.ColumnOrder) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } ws, err := t.db.GetWorkingSet(ctx) @@ -1780,7 +1780,7 @@ func allocatePrefixLengths(idxCols []sql.IndexColumn) []uint16 { // CreateIndex implements sql.IndexAlterableTable func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } if idx.Constraint != sql.IndexConstraint_None && idx.Constraint != sql.IndexConstraint_Unique && idx.Constraint != sql.IndexConstraint_Spatial { @@ -1855,7 +1855,7 @@ func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) err // DropIndex implements sql.IndexAlterableTable func (t *AlterableDoltTable) DropIndex(ctx *sql.Context, indexName string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } // We disallow removing internal dolt_ tables from SQL directly @@ -1883,7 +1883,7 @@ func (t *AlterableDoltTable) DropIndex(ctx *sql.Context, indexName string) error // RenameIndex implements sql.IndexAlterableTable func (t *AlterableDoltTable) RenameIndex(ctx *sql.Context, fromIndexName string, toIndexName string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } // RenameIndex will error if there is a name collision or an index does not exist @@ -2021,7 +2021,7 @@ func (t *AlterableDoltTable) createForeignKey( // AddForeignKey implements sql.ForeignKeyTable func (t *AlterableDoltTable) AddForeignKey(ctx *sql.Context, sqlFk sql.ForeignKeyConstraint) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } if sqlFk.Name != "" && !doltdb.IsValidForeignKeyName(sqlFk.Name) { @@ -2079,7 +2079,7 @@ func (t *AlterableDoltTable) AddForeignKey(ctx *sql.Context, sqlFk sql.ForeignKe // DropForeignKey implements sql.ForeignKeyTable func (t *AlterableDoltTable) DropForeignKey(ctx *sql.Context, fkName string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2107,7 +2107,7 @@ func (t *AlterableDoltTable) DropForeignKey(ctx *sql.Context, fkName string) err // UpdateForeignKey implements sql.ForeignKeyTable func (t *AlterableDoltTable) UpdateForeignKey(ctx *sql.Context, fkName string, sqlFk sql.ForeignKeyConstraint) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2394,7 +2394,7 @@ func (t *AlterableDoltTable) updateFromRoot(ctx *sql.Context, root *doltdb.RootV } func (t *AlterableDoltTable) CreateCheck(ctx *sql.Context, check *sql.CheckDefinition) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2450,7 +2450,7 @@ func (t *AlterableDoltTable) CreateCheck(ctx *sql.Context, check *sql.CheckDefin } func (t *AlterableDoltTable) DropCheck(ctx *sql.Context, chName string) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2501,7 +2501,7 @@ func (t *AlterableDoltTable) ModifyStoredCollation(ctx *sql.Context, collation s } func (t *AlterableDoltTable) ModifyDefaultCollation(ctx *sql.Context, collation sql.CollationID) error { - if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { + if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) From 13cc5e85e458954fb36e9a6fb4b56596ed012c6e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 17:00:24 -0700 Subject: [PATCH 131/167] Resolved import cycle --- .../doltcore/branch_control/branch_control.go | 36 ----------- go/libraries/doltcore/sqle/database.go | 18 +++--- .../doltcore/sqle/dsess/branch_control.go | 59 +++++++++++++++++++ go/libraries/doltcore/sqle/tables.go | 36 +++++------ 4 files changed, 86 insertions(+), 63 deletions(-) create mode 100755 go/libraries/doltcore/sqle/dsess/branch_control.go diff --git a/go/libraries/doltcore/branch_control/branch_control.go b/go/libraries/doltcore/branch_control/branch_control.go index 3acd1fbe9d..6e6238f02d 100644 --- a/go/libraries/doltcore/branch_control/branch_control.go +++ b/go/libraries/doltcore/branch_control/branch_control.go @@ -20,7 +20,6 @@ import ( "fmt" "os" - "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" flatbuffers "github.com/dolthub/flatbuffers/v23/go" "github.com/dolthub/go-mysql-server/sql" "gopkg.in/src-d/go-errors.v1" @@ -201,41 +200,6 @@ func CheckAccess(ctx context.Context, flags Permissions) error { return ErrIncorrectPermissions.New(user, host, branch) } -func CheckAccessForDb(ctx context.Context, db dsess.SqlDatabase, flags Permissions) error { - branchAwareSession := GetBranchAwareSession(ctx) - // A nil session means we're not in the SQL context, so we allow all operations - if branchAwareSession == nil { - return nil - } - - controller := branchAwareSession.GetController() - // Any context that has a non-nil session should always have a non-nil controller, so this is an error - if controller == nil { - return ErrMissingController.New() - } - - controller.Access.RWMutex.RLock() - defer controller.Access.RWMutex.RUnlock() - - user := branchAwareSession.GetUser() - host := branchAwareSession.GetHost() - - if db.RevisionType() != dsess.RevisionTypeBranch { - // not a branch db, no check necessary - return nil - } - - dbName, branch := dsess.SplitRevisionDbName(db.RevisionQualifiedName()) - - // Get the permissions for the branch, user, and host combination - _, perms := controller.Access.Match(dbName, branch, user, host) - // If either the flags match or the user is an admin for this branch, then we allow access - if (perms&flags == flags) || (perms&Permissions_Admin == Permissions_Admin) { - return nil - } - return ErrIncorrectPermissions.New(user, host, branch) -} - // CanCreateBranch returns whether the given context can create a branch with the given name. In general, SQL statements // will almost always return a *sql.Context, so any checks from the SQL path will be able to validate a branch's name. // However, not all CLI commands use *sql.Context, and therefore will not have any user associated with the context. In diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index aee645faec..27add579c1 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -711,7 +711,7 @@ func (db Database) GetHeadRoot(ctx *sql.Context) (*doltdb.RootValue, error) { // DropTable drops the table with the name given. // The planner returns the correct case sensitive name in tableName func (db Database) DropTable(ctx *sql.Context, tableName string) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if doltdb.IsNonAlterableSystemTable(tableName) { @@ -818,7 +818,7 @@ func (db Database) removeTableFromAutoIncrementTracker( // CreateTable creates a table with the name and schema given. func (db Database) CreateTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, collation sql.CollationID) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if strings.ToLower(tableName) == doltdb.DocTableName { @@ -839,7 +839,7 @@ func (db Database) CreateTable(ctx *sql.Context, tableName string, sch sql.Prima // CreateIndexedTable creates a table with the name and schema given. func (db Database) CreateIndexedTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, idxDef sql.IndexDef, collation sql.CollationID) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if strings.ToLower(tableName) == doltdb.DocTableName { @@ -1003,7 +1003,7 @@ func (db Database) CreateTemporaryTable(ctx *sql.Context, tableName string, pkSc // RenameTable implements sql.TableRenamer func (db Database) RenameTable(ctx *sql.Context, oldName, newName string) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } root, err := db.GetRoot(ctx) @@ -1317,7 +1317,7 @@ func (db Database) GetStoredProcedures(ctx *sql.Context) ([]sql.StoredProcedureD // SaveStoredProcedure implements sql.StoredProcedureDatabase. func (db Database) SaveStoredProcedure(ctx *sql.Context, spd sql.StoredProcedureDetails) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } return DoltProceduresAddProcedure(ctx, db, spd) @@ -1325,14 +1325,14 @@ func (db Database) SaveStoredProcedure(ctx *sql.Context, spd sql.StoredProcedure // DropStoredProcedure implements sql.StoredProcedureDatabase. func (db Database) DropStoredProcedure(ctx *sql.Context, name string) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } return DoltProceduresDropProcedure(ctx, db, name) } func (db Database) addFragToSchemasTable(ctx *sql.Context, fragType, name, definition string, created time.Time, existingErr error) (err error) { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } tbl, err := getOrCreateDoltSchemasTable(ctx, db) @@ -1369,7 +1369,7 @@ func (db Database) addFragToSchemasTable(ctx *sql.Context, fragType, name, defin } func (db Database) dropFragFromSchemasTable(ctx *sql.Context, fragType, name string, missingErr error) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } @@ -1458,7 +1458,7 @@ func (db Database) GetCollation(ctx *sql.Context) sql.CollationID { // SetCollation implements the interface sql.CollatedDatabase. func (db Database) SetCollation(ctx *sql.Context, collation sql.CollationID) error { - if err := branch_control.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil { return err } if collation == sql.Collation_Unspecified { diff --git a/go/libraries/doltcore/sqle/dsess/branch_control.go b/go/libraries/doltcore/sqle/dsess/branch_control.go new file mode 100755 index 0000000000..ef0c94eafd --- /dev/null +++ b/go/libraries/doltcore/sqle/dsess/branch_control.go @@ -0,0 +1,59 @@ +// Copyright 2023 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dsess + +import ( + "context" + + "github.com/dolthub/dolt/go/libraries/doltcore/branch_control" +) + +// CheckAccessForDb checks whether the current user has the given permissions for the given database. +// This has to live here, rather than in the branch_control package, to prevent a dependency cycle with that package. +// We could also avoid this by defining branchController as an interface used by dsess. +func CheckAccessForDb(ctx context.Context, db SqlDatabase, flags branch_control.Permissions) error { + branchAwareSession := branch_control.GetBranchAwareSession(ctx) + // A nil session means we're not in the SQL context, so we allow all operations + if branchAwareSession == nil { + return nil + } + + controller := branchAwareSession.GetController() + // Any context that has a non-nil session should always have a non-nil controller, so this is an error + if controller == nil { + return branch_control.ErrMissingController.New() + } + + controller.Access.RWMutex.RLock() + defer controller.Access.RWMutex.RUnlock() + + user := branchAwareSession.GetUser() + host := branchAwareSession.GetHost() + + if db.RevisionType() != RevisionTypeBranch { + // not a branch db, no check necessary + return nil + } + + dbName, branch := SplitRevisionDbName(db.RevisionQualifiedName()) + + // Get the permissions for the branch, user, and host combination + _, perms := controller.Access.Match(dbName, branch, user, host) + // If either the flags match or the user is an admin for this branch, then we allow access + if (perms&flags == flags) || (perms&branch_control.Permissions_Admin == branch_control.Permissions_Admin) { + return nil + } + return branch_control.ErrIncorrectPermissions.New(user, host, branch) +} diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index a810d6b5c2..2650d6af23 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -497,7 +497,7 @@ func (t *WritableDoltTable) WithProjections(colNames []string) sql.Table { // Inserter implements sql.InsertableTable func (t *WritableDoltTable) Inserter(ctx *sql.Context) sql.RowInserter { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -539,7 +539,7 @@ func (t *WritableDoltTable) getTableEditor(ctx *sql.Context) (ed writer.TableWri // Deleter implements sql.DeletableTable func (t *WritableDoltTable) Deleter(ctx *sql.Context) sql.RowDeleter { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -551,7 +551,7 @@ func (t *WritableDoltTable) Deleter(ctx *sql.Context) sql.RowDeleter { // Replacer implements sql.ReplaceableTable func (t *WritableDoltTable) Replacer(ctx *sql.Context) sql.RowReplacer { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -563,7 +563,7 @@ func (t *WritableDoltTable) Replacer(ctx *sql.Context) sql.RowReplacer { // Truncate implements sql.TruncateableTable func (t *WritableDoltTable) Truncate(ctx *sql.Context) (int, error) { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return 0, err } table, err := t.DoltTable.DoltTable(ctx) @@ -700,7 +700,7 @@ func copyConstraintViolationsAndConflicts(ctx context.Context, from, to *doltdb. // Updater implements sql.UpdatableTable func (t *WritableDoltTable) Updater(ctx *sql.Context) sql.RowUpdater { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -712,7 +712,7 @@ func (t *WritableDoltTable) Updater(ctx *sql.Context) sql.RowUpdater { // AutoIncrementSetter implements sql.AutoIncrementTable func (t *WritableDoltTable) AutoIncrementSetter(ctx *sql.Context) sql.AutoIncrementSetter { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return sqlutil.NewStaticErrorEditor(err) } te, err := t.getTableEditor(ctx) @@ -1099,7 +1099,7 @@ func (t *AlterableDoltTable) WithProjections(colNames []string) sql.Table { // AddColumn implements sql.AlterableTable func (t *AlterableDoltTable) AddColumn(ctx *sql.Context, column *sql.Column, order *sql.ColumnOrder) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -1236,7 +1236,7 @@ func (t *AlterableDoltTable) RewriteInserter( newColumn *sql.Column, idxCols []sql.IndexColumn, ) (sql.RowInserter, error) { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return nil, err } err := validateSchemaChange(t.Name(), oldSchema, newSchema, oldColumn, newColumn, idxCols) @@ -1613,7 +1613,7 @@ func (t *AlterableDoltTable) dropColumnData(ctx *sql.Context, updatedTable *dolt // ModifyColumn implements sql.AlterableTable. ModifyColumn operations are only used for operations that change only // the schema of a table, not the data. For those operations, |RewriteInserter| is used. func (t *AlterableDoltTable) ModifyColumn(ctx *sql.Context, columnName string, column *sql.Column, order *sql.ColumnOrder) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } ws, err := t.db.GetWorkingSet(ctx) @@ -1780,7 +1780,7 @@ func allocatePrefixLengths(idxCols []sql.IndexColumn) []uint16 { // CreateIndex implements sql.IndexAlterableTable func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } if idx.Constraint != sql.IndexConstraint_None && idx.Constraint != sql.IndexConstraint_Unique && idx.Constraint != sql.IndexConstraint_Spatial { @@ -1855,7 +1855,7 @@ func (t *AlterableDoltTable) CreateIndex(ctx *sql.Context, idx sql.IndexDef) err // DropIndex implements sql.IndexAlterableTable func (t *AlterableDoltTable) DropIndex(ctx *sql.Context, indexName string) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } // We disallow removing internal dolt_ tables from SQL directly @@ -1883,7 +1883,7 @@ func (t *AlterableDoltTable) DropIndex(ctx *sql.Context, indexName string) error // RenameIndex implements sql.IndexAlterableTable func (t *AlterableDoltTable) RenameIndex(ctx *sql.Context, fromIndexName string, toIndexName string) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } // RenameIndex will error if there is a name collision or an index does not exist @@ -2021,7 +2021,7 @@ func (t *AlterableDoltTable) createForeignKey( // AddForeignKey implements sql.ForeignKeyTable func (t *AlterableDoltTable) AddForeignKey(ctx *sql.Context, sqlFk sql.ForeignKeyConstraint) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } if sqlFk.Name != "" && !doltdb.IsValidForeignKeyName(sqlFk.Name) { @@ -2079,7 +2079,7 @@ func (t *AlterableDoltTable) AddForeignKey(ctx *sql.Context, sqlFk sql.ForeignKe // DropForeignKey implements sql.ForeignKeyTable func (t *AlterableDoltTable) DropForeignKey(ctx *sql.Context, fkName string) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2107,7 +2107,7 @@ func (t *AlterableDoltTable) DropForeignKey(ctx *sql.Context, fkName string) err // UpdateForeignKey implements sql.ForeignKeyTable func (t *AlterableDoltTable) UpdateForeignKey(ctx *sql.Context, fkName string, sqlFk sql.ForeignKeyConstraint) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2394,7 +2394,7 @@ func (t *AlterableDoltTable) updateFromRoot(ctx *sql.Context, root *doltdb.RootV } func (t *AlterableDoltTable) CreateCheck(ctx *sql.Context, check *sql.CheckDefinition) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2450,7 +2450,7 @@ func (t *AlterableDoltTable) CreateCheck(ctx *sql.Context, check *sql.CheckDefin } func (t *AlterableDoltTable) DropCheck(ctx *sql.Context, chName string) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) @@ -2501,7 +2501,7 @@ func (t *AlterableDoltTable) ModifyStoredCollation(ctx *sql.Context, collation s } func (t *AlterableDoltTable) ModifyDefaultCollation(ctx *sql.Context, collation sql.CollationID) error { - if err := branch_control.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { + if err := dsess.CheckAccessForDb(ctx, t.db, branch_control.Permissions_Write); err != nil { return err } root, err := t.getRoot(ctx) From 2e7c13650530f43da228eb39dcefec23be44350a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Thu, 1 Jun 2023 17:13:55 -0700 Subject: [PATCH 132/167] Lots more tests for branch control --- .../sqle/enginetest/branch_control_test.go | 307 ++++++++++++++---- 1 file changed, 251 insertions(+), 56 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go index aae97f1843..9f3661a8ab 100644 --- a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go +++ b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go @@ -382,6 +382,214 @@ var BranchControlBlockTests = []BranchControlBlockTest{ }, } +var BranchControlOtherDbBlockTests = []BranchControlBlockTest{ + { + Name: "INSERT", + Query: "INSERT INTO `mydb/other`.test VALUES (2, 2);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "REPLACE", + Query: "REPLACE INTO `mydb/other`.test VALUES (2, 2);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "UPDATE", + Query: "UPDATE `mydb/other`.test SET pk = 2;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "DELETE", + Query: "DELETE FROM `mydb/other`.test WHERE pk >= 0;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "TRUNCATE", + Query: "TRUNCATE TABLE `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE AUTO_INCREMENT", + SetUpScript: []string{ + "CREATE TABLE `mydb/other`.test2(pk BIGINT PRIMARY KEY AUTO_INCREMENT);", + }, + Query: "ALTER TABLE `mydb/other`.test2 AUTO_INCREMENT = 20;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ADD CHECK", + Query: "ALTER TABLE `mydb/other`.test ADD CONSTRAINT check_1 CHECK (pk > 0);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE DROP CHECK", + SetUpScript: []string{ + "ALTER TABLE `mydb/other`.test ADD CONSTRAINT check_1 CHECK (pk > 0);", + }, + Query: "ALTER TABLE `mydb/other`.test DROP CHECK check_1;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ALTER COLUMN SET DEFAULT", + Query: "ALTER TABLE `mydb/other`.test ALTER COLUMN v1 SET DEFAULT (5);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ALTER COLUMN DROP DEFAULT", + SetUpScript: []string{ + "ALTER TABLE `mydb/other`.test ALTER COLUMN v1 SET DEFAULT (5);", + }, + Query: "ALTER TABLE `mydb/other`.test ALTER COLUMN v1 DROP DEFAULT;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ADD FOREIGN KEY", + SetUpScript: []string{ + "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", + "CREATE TABLE `mydb/other`.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT UNIQUE);", + }, + Query: "ALTER TABLE `mydb/other`.test2 ADD CONSTRAINT fk_1 FOREIGN KEY (v1) REFERENCES test (v1);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE DROP FOREIGN KEY", + SetUpScript: []string{ + "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", + "CREATE TABLE `mydb/other`.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT UNIQUE, CONSTRAINT fk_1 FOREIGN KEY (v1) REFERENCES test (v1));", + }, + Query: "ALTER TABLE `mydb/other`.test2 DROP FOREIGN KEY fk_1;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ADD INDEX", + Query: "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE DROP INDEX", + SetUpScript: []string{ + "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", + }, + Query: "ALTER TABLE `mydb/other`.test DROP INDEX idx_v1;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE RENAME INDEX", + SetUpScript: []string{ + "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", + }, + Query: "ALTER TABLE `mydb/other`.test RENAME INDEX idx_v1 TO idx_v1_new;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ADD PRIMARY KEY", + SetUpScript: []string{ + "CREATE TABLE `mydb/other`.test2 (v1 BIGINT, v2 BIGINT);", + }, + Query: "ALTER TABLE `mydb/other`.test2 ADD PRIMARY KEY (v1, v2);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE DROP PRIMARY KEY", + Query: "ALTER TABLE `mydb/other`.test DROP PRIMARY KEY;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE RENAME", + Query: "ALTER TABLE `mydb/other`.test RENAME TO test_new;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "RENAME TABLE", + Query: "RENAME TABLE `mydb/other`.test TO test_new;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE ADD COLUMN", + Query: "ALTER TABLE `mydb/other`.test ADD COLUMN v2 BIGINT;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE DROP COLUMN", + Query: "ALTER TABLE `mydb/other`.test DROP COLUMN v1;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE CHANGE COLUMN", + Query: "ALTER TABLE `mydb/other`.test CHANGE COLUMN v1 v1_new BIGINT;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE MODIFY COLUMN", + Query: "ALTER TABLE `mydb/other`.test MODIFY COLUMN v1 TINYINT;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "ALTER TABLE RENAME COLUMN", + Query: "ALTER TABLE `mydb/other`.test RENAME COLUMN v1 TO v1_new;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "CREATE INDEX", + Query: "CREATE INDEX idx_v1 ON `mydb/other`.test (v1);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "DROP INDEX", + SetUpScript: []string{ + "CREATE INDEX idx_v1 ON `mydb/other`.test (v1);", + }, + Query: "DROP INDEX idx_v1 ON `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "CREATE VIEW", + Query: "CREATE VIEW view_1 AS SELECT * FROM `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "DROP VIEW", + SetUpScript: []string{ + "CREATE VIEW view_1 AS SELECT * FROM `mydb/other`.test;", + }, + Query: "DROP VIEW view_1;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "CREATE TRIGGER", + Query: "CREATE TRIGGER trigger_1 BEFORE INSERT ON `mydb/other`.test FOR EACH ROW SET NEW.v1 = 4;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "DROP TRIGGER", + SetUpScript: []string{ + "CREATE TRIGGER trigger_1 BEFORE INSERT ON `mydb/other`.test FOR EACH ROW SET NEW.v1 = 4;", + }, + Query: "DROP TRIGGER trigger_1;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "CREATE TABLE", + Query: "CREATE TABLE `mydb/other`.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT);", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "CREATE TABLE LIKE", + Query: "CREATE TABLE `mydb/other`.test2 LIKE `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "CREATE TABLE AS SELECT", + Query: "CREATE TABLE `mydb/other`.test2 AS SELECT * FROM `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, + { + Name: "DROP TABLE", + Query: "DROP TABLE `mydb/other`.test;", + ExpectedErr: branch_control.ErrIncorrectPermissions, + }, +} + var BranchControlTests = []BranchControlTest{ { Name: "Namespace entries block", @@ -1201,59 +1409,46 @@ func TestBranchControl(t *testing.T) { } func TestBranchControlBlocks(t *testing.T) { - // for _, test := range BranchControlBlockTests { - // harness := newDoltHarness(t) - // defer harness.Close() - // t.Run(test.Name, func(t *testing.T) { - // engine, err := harness.NewEngine(t) - // require.NoError(t, err) - // defer engine.Close() - // - // rootCtx := enginetest.NewContext(harness) - // rootCtx.NewCtxWithClient(sql.Client{ - // User: "root", - // Address: "localhost", - // }) - // engine.Analyzer.Catalog.MySQLDb.AddRootAccount() - // engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) - // - // for _, statement := range append(TestUserSetUpScripts, test.SetUpScript...) { - // enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) - // } - // - // userCtx := enginetest.NewContextWithClient(harness, sql.Client{ - // User: "testuser", - // Address: "localhost", - // }) - // enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) - // - // addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write'), ('%', 'other', 'testuser', 'localhost', 'write');" - // addUserQueryResults := []sql.Row{{types.NewOkResult(2)}} - // enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) - // - // sch, iter, err := engine.Query(userCtx, test.Query) - // if err == nil { - // _, err = sql.RowIterToRows(userCtx, sch, iter) - // } - // assert.NoError(t, err) - // }) - // } - - // These tests are run with permission on main but not other - var branchRevisionTests = []BranchControlBlockTest{ - { - Name: "INSERT on branch db, permissions on main", - Query: "INSERT INTO `mydb/other`.test VALUES (2, 2);", - ExpectedErr: branch_control.ErrIncorrectPermissions, - }, - { - Name: "DELETE on branch db, permissions on main", - Query: "DELETE from `mydb/other`.test;", - ExpectedErr: branch_control.ErrIncorrectPermissions, - }, + for _, test := range BranchControlBlockTests { + harness := newDoltHarness(t) + defer harness.Close() + t.Run(test.Name, func(t *testing.T) { + engine, err := harness.NewEngine(t) + require.NoError(t, err) + defer engine.Close() + + rootCtx := enginetest.NewContext(harness) + rootCtx.NewCtxWithClient(sql.Client{ + User: "root", + Address: "localhost", + }) + engine.Analyzer.Catalog.MySQLDb.AddRootAccount() + engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) + + for _, statement := range append(TestUserSetUpScripts, test.SetUpScript...) { + enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) + } + + userCtx := enginetest.NewContextWithClient(harness, sql.Client{ + User: "testuser", + Address: "localhost", + }) + enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) + + addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write'), ('%', 'other', 'testuser', 'localhost', 'write');" + addUserQueryResults := []sql.Row{{types.NewOkResult(2)}} + enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) + + sch, iter, err := engine.Query(userCtx, test.Query) + if err == nil { + _, err = sql.RowIterToRows(userCtx, sch, iter) + } + assert.NoError(t, err) + }) } - for _, test := range branchRevisionTests { + // These tests are run with permission on main but not other + for _, test := range BranchControlOtherDbBlockTests { harness := newDoltHarness(t) defer harness.Close() t.Run(test.Name, func(t *testing.T) { @@ -1273,9 +1468,9 @@ func TestBranchControlBlocks(t *testing.T) { enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) } - // addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write');" - // addUserQueryResults := []sql.Row{{types.NewOkResult(1)}} - // enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) + addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write');" + addUserQueryResults := []sql.Row{{types.NewOkResult(1)}} + enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) userCtx := enginetest.NewContextWithClient(harness, sql.Client{ User: "testuser", @@ -1283,8 +1478,8 @@ func TestBranchControlBlocks(t *testing.T) { }) enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) - addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'other', 'testuser', 'localhost', 'write');" - addUserQueryResults := []sql.Row{{types.NewOkResult(1)}} + addUserQuery = "INSERT INTO dolt_branch_control VALUES ('%', 'other', 'testuser', 'localhost', 'write');" + addUserQueryResults = []sql.Row{{types.NewOkResult(1)}} enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) sch, iter, err := engine.Query(userCtx, test.Query) From 64d8cdeab911186a3bd4ee991222ba3c26df22a6 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 08:52:07 -0700 Subject: [PATCH 133/167] Skipped tests for missing functionality --- .../sqle/enginetest/branch_control_test.go | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go index 9f3661a8ab..eeedc572cf 100644 --- a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go +++ b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go @@ -56,6 +56,7 @@ type BranchControlBlockTest struct { SetUpScript []string Query string ExpectedErr *errors.Kind + SkipMessage string } // TestUserSetUpScripts creates a user named "testuser@localhost", and grants them privileges on all databases and @@ -448,14 +449,14 @@ var BranchControlOtherDbBlockTests = []BranchControlBlockTest{ "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", "CREATE TABLE `mydb/other`.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT UNIQUE);", }, - Query: "ALTER TABLE `mydb/other`.test2 ADD CONSTRAINT fk_1 FOREIGN KEY (v1) REFERENCES test (v1);", + Query: "ALTER TABLE `mydb/other`.test2 ADD CONSTRAINT fk_1 FOREIGN KEY (v1) REFERENCES `mydb/other`.test (v1);", ExpectedErr: branch_control.ErrIncorrectPermissions, }, { Name: "ALTER TABLE DROP FOREIGN KEY", SetUpScript: []string{ "ALTER TABLE `mydb/other`.test ADD INDEX idx_v1 (v1);", - "CREATE TABLE `mydb/other`.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT UNIQUE, CONSTRAINT fk_1 FOREIGN KEY (v1) REFERENCES test (v1));", + "CREATE TABLE `mydb/other`.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT UNIQUE, CONSTRAINT fk_1 FOREIGN KEY (v1) REFERENCES `mydb/other`.test (v1));", }, Query: "ALTER TABLE `mydb/other`.test2 DROP FOREIGN KEY fk_1;", ExpectedErr: branch_control.ErrIncorrectPermissions, @@ -498,11 +499,13 @@ var BranchControlOtherDbBlockTests = []BranchControlBlockTest{ Name: "ALTER TABLE RENAME", Query: "ALTER TABLE `mydb/other`.test RENAME TO test_new;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "RENAME TABLE", Query: "RENAME TABLE `mydb/other`.test TO test_new;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "ALTER TABLE ADD COLUMN", @@ -546,6 +549,7 @@ var BranchControlOtherDbBlockTests = []BranchControlBlockTest{ Name: "CREATE VIEW", Query: "CREATE VIEW view_1 AS SELECT * FROM `mydb/other`.test;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "DROP VIEW", @@ -554,19 +558,22 @@ var BranchControlOtherDbBlockTests = []BranchControlBlockTest{ }, Query: "DROP VIEW view_1;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "CREATE TRIGGER", Query: "CREATE TRIGGER trigger_1 BEFORE INSERT ON `mydb/other`.test FOR EACH ROW SET NEW.v1 = 4;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "DROP TRIGGER", SetUpScript: []string{ "CREATE TRIGGER trigger_1 BEFORE INSERT ON `mydb/other`.test FOR EACH ROW SET NEW.v1 = 4;", }, - Query: "DROP TRIGGER trigger_1;", + Query: "DROP TRIGGER `mydb/other`.trigger_1;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "CREATE TABLE", @@ -577,6 +584,7 @@ var BranchControlOtherDbBlockTests = []BranchControlBlockTest{ Name: "CREATE TABLE LIKE", Query: "CREATE TABLE `mydb/other`.test2 LIKE `mydb/other`.test;", ExpectedErr: branch_control.ErrIncorrectPermissions, + SkipMessage: "https://github.com/dolthub/dolt/issues/6078", }, { Name: "CREATE TABLE AS SELECT", @@ -1410,9 +1418,14 @@ func TestBranchControl(t *testing.T) { func TestBranchControlBlocks(t *testing.T) { for _, test := range BranchControlBlockTests { - harness := newDoltHarness(t) - defer harness.Close() t.Run(test.Name, func(t *testing.T) { + if test.SkipMessage != "" { + t.Skip(test.SkipMessage) + } + + harness := newDoltHarness(t) + defer harness.Close() + engine, err := harness.NewEngine(t) require.NoError(t, err) defer engine.Close() @@ -1449,9 +1462,14 @@ func TestBranchControlBlocks(t *testing.T) { // These tests are run with permission on main but not other for _, test := range BranchControlOtherDbBlockTests { - harness := newDoltHarness(t) - defer harness.Close() - t.Run(test.Name, func(t *testing.T) { + t.Run("OtherDB_" + test.Name, func(t *testing.T) { + if test.SkipMessage != "" { + t.Skip(test.SkipMessage) + } + + harness := newDoltHarness(t) + defer harness.Close() + engine, err := harness.NewEngine(t) require.NoError(t, err) defer engine.Close() @@ -1489,5 +1507,4 @@ func TestBranchControlBlocks(t *testing.T) { assert.NoError(t, err) }) } - } From 3c97d18ff2f21cd7f60fdddf2d5d2aa8db85fac7 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 10:07:53 -0700 Subject: [PATCH 134/167] Additional info schema tests --- .../sqle/enginetest/dolt_engine_test.go | 8 ++ .../doltcore/sqle/enginetest/dolt_queries.go | 103 ++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 90b6ab2b99..0e435ffdc4 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -384,6 +384,14 @@ func TestInfoSchema(t *testing.T) { h := newDoltHarness(t) defer h.Close() enginetest.TestInfoSchema(t, h) + + for _, script := range DoltInfoSchemaScripts { + func() { + harness := newDoltHarness(t) + defer harness.Close() + enginetest.TestScript(t, harness, script) + }() + } } func TestColumnAliases(t *testing.T) { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index f8a059432c..45d424d928 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -2112,6 +2112,109 @@ var DoltCheckoutScripts = []queries.ScriptTest{ }, } +var DoltInfoSchemaScripts = []queries.ScriptTest{ + { + Name: "info_schema changes with dolt_checkout", + SetUpScript: []string{ + "create table t (a int primary key, b int);", + "call dolt_commit('-Am', 'creating table t');", + "call dolt_branch('b2');", + "call dolt_branch('b3');", + "call dolt_checkout('b2');", + "alter table t add column c int;", + "call dolt_commit('-am', 'added column c on branch b2');", + "call dolt_checkout('b3');", + "alter table t add column d int;", + "call dolt_commit('-am', 'added column d on branch b3');", + "call dolt_checkout('main');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select column_name from information_schema.columns where table_schema = 'mydb' and table_name = 't' order by 1;", + Expected: []sql.Row{{"a"}, {"b"}}, + }, + { + Query: "call dolt_checkout('b2');", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b2"}}, + }, + { + Query: "select column_name from information_schema.columns where table_schema = 'mydb' and table_name = 't' order by 1;", + Expected: []sql.Row{{"a"}, {"b"}, {"c"}}, + }, + { + Query: "call dolt_checkout('b3');", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b3"}}, + }, + { + Query: "select column_name from information_schema.columns where table_schema = 'mydb' and table_name = 't' order by 1;", + Expected: []sql.Row{{"a"}, {"b"}, {"d"}}, + }, + }, + }, + { + Name: "info_schema changes with USE", + SetUpScript: []string{ + "create table t (a int primary key, b int);", + "call dolt_commit('-Am', 'creating table t');", + "call dolt_branch('b2');", + "call dolt_branch('b3');", + "call dolt_checkout('b2');", + "alter table t add column c int;", + "call dolt_commit('-am', 'added column c on branch b2');", + "call dolt_checkout('b3');", + "alter table t add column d int;", + "call dolt_commit('-am', 'added column d on branch b3');", + "use mydb/main;", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "select active_branch();", + Expected: []sql.Row{{"main"}}, + }, + { + Query: "select column_name from information_schema.columns where table_schema = 'mydb' and table_name = 't' order by 1;", + Expected: []sql.Row{{"a"}, {"b"}}, + }, + { + Query: "use mydb/b2;", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b2"}}, + }, + { + Query: "select column_name from information_schema.columns where table_schema = 'mydb' and table_name = 't' order by 1;", + Expected: []sql.Row{{"a"}, {"b"}, {"c"}}, + }, + { + Query: "use mydb/b3;", + SkipResultsCheck: true, + }, + { + Query: "select active_branch();", + Expected: []sql.Row{{"b3"}}, + }, + { + Query: "select column_name from information_schema.columns where table_schema = 'mydb' and table_name = 't' order by 1;", + Expected: []sql.Row{{"a"}, {"b"}, {"d"}}, + }, + }, + }, +} + var DoltBranchScripts = []queries.ScriptTest{ { Name: "Create branches from HEAD with dolt_branch procedure", From daf8ecf2ccecb5a8dbc5c81255b60943a891053f Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 12:51:04 -0700 Subject: [PATCH 135/167] Use the default / checked out branch when establishing the database-level checked out branch during session init. --- .../doltcore/sqle/database_provider.go | 43 +++++++-------- go/libraries/doltcore/sqle/dsess/session.go | 53 ++++++++++++++++++- .../sqle/dsess/session_db_provider.go | 3 ++ 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index d4c8a52e4e..c864462823 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1025,6 +1025,25 @@ func resolveAncestorSpec(ctx *sql.Context, revSpec string, ddb *doltdb.DoltDB) ( return hash.String(), nil } +// BaseDatabase returns the base database for the specified database name. Meant for informational purposes when +// managing the session initialization only. Use SessionDatabase for normal database retrieval. +func (p DoltDatabaseProvider) BaseDatabase(ctx *sql.Context, name string) (dsess.SqlDatabase, bool) { + baseName := name + isRevisionDbName := strings.Contains(name, dsess.DbRevisionDelimiter) + + if isRevisionDbName { + parts := strings.SplitN(name, dsess.DbRevisionDelimiter, 2) + baseName = parts[0] + } + + var ok bool + p.mu.RLock() + db, ok := p.databases[strings.ToLower(baseName)] + p.mu.RUnlock() + + return db, ok +} + // SessionDatabase implements dsess.SessionDatabaseProvider func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (dsess.SqlDatabase, bool, error) { baseName := name @@ -1081,27 +1100,9 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds if !ok { usingDefaultBranch = true - // First check the global variable for the default branch - _, val, ok := sql.SystemVariables.GetGlobal(dsess.DefaultBranchKey(baseName)) - if ok { - head = val.(string) - branchRef, err := ref.Parse(head) - if err == nil { - head = branchRef.GetPath() - } else { - head = "" - // continue to below - } - } - - // Fall back to the database's checked out branch - if head == "" { - rsr := db.DbData().Rsr - headRef, err := rsr.CWBHeadRef() - if err != nil { - return nil, false, err - } - head = headRef.GetPath() + head, err = dsess.DefaultHead(baseName, db) + if err != nil { + return nil, false, err } } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index b34a5a5a4f..f25f1e69f8 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1137,7 +1137,21 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } sessionState.dbName = baseName - sessionState.checkedOutRevSpec = db.Revision() + + baseDb, ok := d.provider.BaseDatabase(ctx, baseName) + if !ok { + d.mu.Unlock() + return fmt.Errorf("unable to find database %s, this is a bug", baseName) + } + + // The checkedOutRevSpec should be the checked out branch of the database if available, or the revision + // string otherwise + sessionState.checkedOutRevSpec, err = DefaultHead(baseName, baseDb) + if err != nil { + d.mu.Unlock() + return err + } + sessionState.currRevType = db.RevisionType() sessionState.currRevSpec = db.Revision() } @@ -1623,3 +1637,40 @@ func TransactionRoot(ctx *sql.Context, db SqlDatabase) (hash.Hash, error) { return nomsRoot, nil } + +// DefaultHead returns the head for the database given when one isn't specified +func DefaultHead(baseName string, db SqlDatabase) (string, error) { + head := "" + + // First check the global variable for the default branch + _, val, ok := sql.SystemVariables.GetGlobal(DefaultBranchKey(baseName)) + if ok { + head = val.(string) + branchRef, err := ref.Parse(head) + if err == nil { + head = branchRef.GetPath() + } else { + head = "" + // continue to below + } + } + + // Fall back to the database's initially checked out branch + if head == "" { + rsr := db.DbData().Rsr + if rsr != nil { + headRef, err := rsr.CWBHeadRef() + if err != nil { + return "", err + } + head = headRef.GetPath() + } + } + + if head == "" { + head = db.Revision() + } + + return head, nil +} + diff --git a/go/libraries/doltcore/sqle/dsess/session_db_provider.go b/go/libraries/doltcore/sqle/dsess/session_db_provider.go index 30f25b4e03..a3d34ce4aa 100644 --- a/go/libraries/doltcore/sqle/dsess/session_db_provider.go +++ b/go/libraries/doltcore/sqle/dsess/session_db_provider.go @@ -91,6 +91,9 @@ type DoltDatabaseProvider interface { // SessionDatabase returns the SessionDatabase for the specified database, which may name a revision of a base // database. SessionDatabase(ctx *sql.Context, dbName string) (SqlDatabase, bool, error) + // BaseDatabase returns the base database for the specified database name. Meant for informational purposes when + // managing the session initialization only. Use SessionDatabase for normal database retrieval. + BaseDatabase(ctx *sql.Context, dbName string) (SqlDatabase, bool) // DoltDatabases returns all databases known to this provider. DoltDatabases() []SqlDatabase } From 39a6a3e62e9fed35ef1d511a227e4f371f525db5 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 13:10:00 -0700 Subject: [PATCH 136/167] Newest gms --- go/go.mod | 310 +++---- go/go.sum | 2324 ++++++++++++++++++++++++++--------------------------- 2 files changed, 1317 insertions(+), 1317 deletions(-) diff --git a/go/go.mod b/go/go.mod index 47f07503f7..cacb4f5333 100755 --- a/go/go.mod +++ b/go/go.mod @@ -1,155 +1,155 @@ -module github.com/dolthub/dolt/go - -require ( - cloud.google.com/go/storage v1.12.0 - github.com/BurntSushi/toml v1.1.0 - github.com/HdrHistogram/hdrhistogram-go v1.1.2 - github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db - github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 - github.com/attic-labs/kingpin v2.2.7-0.20180312050558-442efcfac769+incompatible - github.com/aws/aws-sdk-go v1.34.0 - github.com/bcicen/jstream v1.0.0 - github.com/boltdb/bolt v1.3.1 - github.com/denisbrodbeck/machineid v1.0.1 - github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi v0.0.0-20201005193433-3ee972b1d078 - github.com/dolthub/fslock v0.0.3 - github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 - github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 - github.com/dolthub/vitess v0.0.0-20230531182027-fe0363298c52 - github.com/dustin/go-humanize v1.0.0 - github.com/fatih/color v1.13.0 - github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 - github.com/go-sql-driver/mysql v1.6.0 - github.com/gocraft/dbr/v2 v2.7.2 - github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.1 - github.com/google/uuid v1.2.0 - github.com/jpillora/backoff v1.0.0 - github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d - github.com/mattn/go-isatty v0.0.16 - github.com/mattn/go-runewidth v0.0.13 - github.com/pkg/errors v0.9.1 - github.com/pkg/profile v1.5.0 - github.com/rivo/uniseg v0.2.0 - github.com/sergi/go-diff v1.1.0 - github.com/shopspring/decimal v1.2.0 - github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6 - github.com/sirupsen/logrus v1.8.1 - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 - github.com/stretchr/testify v1.8.2 - github.com/tealeg/xlsx v1.0.5 - github.com/tklauser/go-sysconf v0.3.9 // indirect - go.uber.org/zap v1.15.0 - golang.org/x/crypto v0.1.0 - golang.org/x/net v0.7.0 - golang.org/x/sync v0.1.0 - golang.org/x/sys v0.6.0 - google.golang.org/api v0.32.0 - google.golang.org/grpc v1.49.0 - google.golang.org/protobuf v1.28.1 - gopkg.in/square/go-jose.v2 v2.5.1 - gopkg.in/src-d/go-errors.v1 v1.0.0 - gopkg.in/yaml.v2 v2.4.0 -) - -require ( - github.com/Shopify/toxiproxy/v2 v2.5.0 - github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible - github.com/cenkalti/backoff/v4 v4.1.3 - github.com/cespare/xxhash v1.1.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.15.1-0.20230602002747-63ffc9c1b72f - github.com/dolthub/swiss v0.1.0 - github.com/goccy/go-json v0.10.2 - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/hashicorp/golang-lru/v2 v2.0.2 - github.com/jmoiron/sqlx v1.3.4 - github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6 - github.com/kylelemons/godebug v1.1.0 - github.com/mitchellh/go-ps v1.0.0 - github.com/prometheus/client_golang v1.13.0 - github.com/rs/zerolog v1.28.0 - github.com/shirou/gopsutil/v3 v3.22.1 - github.com/vbauerster/mpb v3.4.0+incompatible - github.com/vbauerster/mpb/v8 v8.0.2 - github.com/xitongsys/parquet-go v1.6.1 - github.com/xitongsys/parquet-go-source v0.0.0-20211010230925-397910c5e371 - github.com/zeebo/blake3 v0.2.3 - github.com/zeebo/xxh3 v1.0.2 - go.etcd.io/bbolt v1.3.6 - go.opentelemetry.io/otel v1.7.0 - go.opentelemetry.io/otel/exporters/jaeger v1.7.0 - go.opentelemetry.io/otel/sdk v1.7.0 - go.opentelemetry.io/otel/trace v1.7.0 - golang.org/x/text v0.7.0 - gonum.org/v1/plot v0.11.0 - gopkg.in/yaml.v3 v3.0.1 -) - -require ( - cloud.google.com/go v0.66.0 // indirect - git.sr.ht/~sbinet/gg v0.3.1 // indirect - github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect - github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect - github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e // indirect - github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72 // indirect - github.com/dolthub/maphash v0.0.0-20221220182448-74e1e1ea1577 // indirect - github.com/go-fonts/liberation v0.2.0 // indirect - github.com/go-kit/kit v0.10.0 // indirect - github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 // indirect - github.com/go-logr/logr v1.2.3 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-pdf/fpdf v0.6.0 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/jstemmer/go-junit-report v0.9.1 // indirect - github.com/klauspost/compress v1.10.10 // indirect - github.com/klauspost/cpuid/v2 v2.0.12 // indirect - github.com/lestrrat-go/strftime v1.0.4 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/mitchellh/hashstructure v1.1.0 // indirect - github.com/pierrec/lz4/v4 v4.1.6 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/rs/xid v1.4.0 // indirect - github.com/tetratelabs/wazero v1.1.0 // indirect - github.com/tidwall/gjson v1.14.4 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.1 // indirect - github.com/tidwall/sjson v1.2.5 // indirect - github.com/tklauser/numcpus v0.3.0 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect - go.opencensus.io v0.22.4 // indirect - go.uber.org/atomic v1.6.0 // indirect - go.uber.org/multierr v1.5.0 // indirect - golang.org/x/image v0.5.0 // indirect - golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect - golang.org/x/tools v0.3.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect -) - -replace github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi => ./gen/proto/dolt/services/eventsapi - -go 1.19 +module github.com/dolthub/dolt/go + +require ( + cloud.google.com/go/storage v1.12.0 + github.com/BurntSushi/toml v1.1.0 + github.com/HdrHistogram/hdrhistogram-go v1.1.2 + github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db + github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 + github.com/attic-labs/kingpin v2.2.7-0.20180312050558-442efcfac769+incompatible + github.com/aws/aws-sdk-go v1.34.0 + github.com/bcicen/jstream v1.0.0 + github.com/boltdb/bolt v1.3.1 + github.com/denisbrodbeck/machineid v1.0.1 + github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi v0.0.0-20201005193433-3ee972b1d078 + github.com/dolthub/fslock v0.0.3 + github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 + github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 + github.com/dolthub/vitess v0.0.0-20230531182027-fe0363298c52 + github.com/dustin/go-humanize v1.0.0 + github.com/fatih/color v1.13.0 + github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 + github.com/go-sql-driver/mysql v1.6.0 + github.com/gocraft/dbr/v2 v2.7.2 + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.1 + github.com/google/uuid v1.2.0 + github.com/jpillora/backoff v1.0.0 + github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d + github.com/mattn/go-isatty v0.0.16 + github.com/mattn/go-runewidth v0.0.13 + github.com/pkg/errors v0.9.1 + github.com/pkg/profile v1.5.0 + github.com/rivo/uniseg v0.2.0 + github.com/sergi/go-diff v1.1.0 + github.com/shopspring/decimal v1.2.0 + github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6 + github.com/sirupsen/logrus v1.8.1 + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 + github.com/stretchr/testify v1.8.2 + github.com/tealeg/xlsx v1.0.5 + github.com/tklauser/go-sysconf v0.3.9 // indirect + go.uber.org/zap v1.15.0 + golang.org/x/crypto v0.1.0 + golang.org/x/net v0.7.0 + golang.org/x/sync v0.1.0 + golang.org/x/sys v0.6.0 + google.golang.org/api v0.32.0 + google.golang.org/grpc v1.49.0 + google.golang.org/protobuf v1.28.1 + gopkg.in/square/go-jose.v2 v2.5.1 + gopkg.in/src-d/go-errors.v1 v1.0.0 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/Shopify/toxiproxy/v2 v2.5.0 + github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible + github.com/cenkalti/backoff/v4 v4.1.3 + github.com/cespare/xxhash v1.1.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.15.1-0.20230602200348-162f21795cab + github.com/dolthub/swiss v0.1.0 + github.com/goccy/go-json v0.10.2 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 + github.com/hashicorp/golang-lru/v2 v2.0.2 + github.com/jmoiron/sqlx v1.3.4 + github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6 + github.com/kylelemons/godebug v1.1.0 + github.com/mitchellh/go-ps v1.0.0 + github.com/prometheus/client_golang v1.13.0 + github.com/rs/zerolog v1.28.0 + github.com/shirou/gopsutil/v3 v3.22.1 + github.com/vbauerster/mpb v3.4.0+incompatible + github.com/vbauerster/mpb/v8 v8.0.2 + github.com/xitongsys/parquet-go v1.6.1 + github.com/xitongsys/parquet-go-source v0.0.0-20211010230925-397910c5e371 + github.com/zeebo/blake3 v0.2.3 + github.com/zeebo/xxh3 v1.0.2 + go.etcd.io/bbolt v1.3.6 + go.opentelemetry.io/otel v1.7.0 + go.opentelemetry.io/otel/exporters/jaeger v1.7.0 + go.opentelemetry.io/otel/sdk v1.7.0 + go.opentelemetry.io/otel/trace v1.7.0 + golang.org/x/text v0.7.0 + gonum.org/v1/plot v0.11.0 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + cloud.google.com/go v0.66.0 // indirect + git.sr.ht/~sbinet/gg v0.3.1 // indirect + github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect + github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e // indirect + github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72 // indirect + github.com/dolthub/maphash v0.0.0-20221220182448-74e1e1ea1577 // indirect + github.com/go-fonts/liberation v0.2.0 // indirect + github.com/go-kit/kit v0.10.0 // indirect + github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-pdf/fpdf v0.6.0 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jstemmer/go-junit-report v0.9.1 // indirect + github.com/klauspost/compress v1.10.10 // indirect + github.com/klauspost/cpuid/v2 v2.0.12 // indirect + github.com/lestrrat-go/strftime v1.0.4 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mitchellh/hashstructure v1.1.0 // indirect + github.com/pierrec/lz4/v4 v4.1.6 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/rs/xid v1.4.0 // indirect + github.com/tetratelabs/wazero v1.1.0 // indirect + github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect + github.com/tklauser/numcpus v0.3.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.opencensus.io v0.22.4 // indirect + go.uber.org/atomic v1.6.0 // indirect + go.uber.org/multierr v1.5.0 // indirect + golang.org/x/image v0.5.0 // indirect + golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + golang.org/x/tools v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect +) + +replace github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi => ./gen/proto/dolt/services/eventsapi + +go 1.19 diff --git a/go/go.sum b/go/go.sum index a0b87fde36..1c0a4822d1 100755 --- a/go/go.sum +++ b/go/go.sum @@ -1,1162 +1,1162 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.66.0 h1:DZeAkuQGQqnm9Xv36SbMJEU8aFBz4wL04UpMWPWwjzg= -cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.12.0 h1:4y3gHptW1EHVtcPAVE0eBBlFuGqEejTTG3KdIE0lUX4= -cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -git.sr.ht/~sbinet/gg v0.3.1 h1:LNhjNn8DerC8f9DHLz6lS0YYul/b602DUxDgGkd/Aik= -git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= -github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc= -github.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8= -github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= -github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible h1:QoRMR0TCctLDqBCMyOu1eXdZyMw3F7uGA9qPn2J4+R8= -github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.0.0-20181112125854-24918abba929/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714 h1:Jz3KVLYY5+JO7rDiX0sAuRGtuv2vG01r17Y9nLMWNUw= -github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/attic-labs/kingpin v2.2.7-0.20180312050558-442efcfac769+incompatible h1:wd5mq8xSfwCYd1JpQ309s+3tTlP/gifcG2awOA3x5Vk= -github.com/attic-labs/kingpin v2.2.7-0.20180312050558-442efcfac769+incompatible/go.mod h1:Cp18FeDCvsK+cD2QAGkqerGjrgSXLiJWnjHeY2mneBc= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.30.19/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.34.0 h1:brux2dRrlwCF5JhTL7MUT3WUwo9zfDHZZp3+g3Mvlmo= -github.com/aws/aws-sdk-go v1.34.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= -github.com/aws/aws-sdk-go-v2/config v1.5.0/go.mod h1:RWlPOAW3E3tbtNAqTwvSW54Of/yP3oiZXMI0xfUdjyA= -github.com/aws/aws-sdk-go-v2/credentials v1.3.1/go.mod h1:r0n73xwsIVagq8RsxmZbGSRQFj9As3je72C2WzUIToc= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.3.0/go.mod h1:2LAuqPx1I6jNfaGDucWfA2zqQCYCOMCDHiCOciALyNw= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.3.2/go.mod h1:qaqQiHSrOUVOfKe6fhgQ6UzhxjwqVW8aHNegd6Ws4w4= -github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1/go.mod h1:Zy8smImhTdOETZqfyn01iNOe0CNggVbPjCajyaz6Gvg= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.1/go.mod h1:v33JQ57i2nekYTA70Mb+O18KeH4KqhdqxTJZNK1zdRE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.1/go.mod h1:zceowr5Z1Nh2WVP8bf/3ikB41IZW59E4yIYbg+pC6mw= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.1/go.mod h1:6EQZIwNNvHpq/2/QSJnp4+ECvqIy55w95Ofs0ze+nGQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.11.1/go.mod h1:XLAGFrEjbvMCLvAtWLLP32yTv8GpBquCApZEycDLunI= -github.com/aws/aws-sdk-go-v2/service/sso v1.3.1/go.mod h1:J3A3RGUvuCZjvSuZEcOpHDnzZP/sKbhDWV2T1EOzFIM= -github.com/aws/aws-sdk-go-v2/service/sts v1.6.0/go.mod h1:q7o0j7d7HrJk/vr9uUt3BVRASvcU7gYZB9PUgPiByXg= -github.com/aws/smithy-go v1.6.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/bcicen/jstream v1.0.0 h1:gOi+Sn9mHrpePlENynPKA6Dra/PjLaIpqrTevhfvLAA= -github.com/bcicen/jstream v1.0.0/go.mod h1:9ielPxqFry7Y4Tg3j4BfjPocfJ3TbsRtXOAYXYmRuAQ= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/colinmarc/hdfs/v2 v2.1.1/go.mod h1:M3x+k8UKKmxtFu++uAZ0OtDU8jR3jnaZIAc6yK4Ue0c= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creasty/defaults v1.6.0 h1:ltuE9cfphUtlrBeomuu8PEyISTXnxqkBIoQfXgv7BSc= -github.com/creasty/defaults v1.6.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= -github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= -github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= -github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1Gms9599cr0REMww= -github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2/go.mod h1:mIEZOHnFx4ZMQeawhw9rhsj+0zwQj7adVsnBX7t+eKY= -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-20230524105445-af7e7991c97e h1:kPsT4a47cw1+y/N5SSCkma7FhAPw7KeGmD6c9PBZW9Y= -github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168= -github.com/dolthub/go-mysql-server v0.15.1-0.20230602002747-63ffc9c1b72f h1:f7H66wimomDcGtzBpTa7slxUIPUKY0t3nweGuS/GgQo= -github.com/dolthub/go-mysql-server v0.15.1-0.20230602002747-63ffc9c1b72f/go.mod h1:uXHw3YMx/PLUe5vUaFDdr66lVHiabnn0xi1LZg3T+FA= -github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= -github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto= -github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72 h1:NfWmngMi1CYUWU4Ix8wM+USEhjc+mhPlT9JUR/anvbQ= -github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72/go.mod h1:ZWUdY4iszqRQ8OcoXClkxiAVAoWoK3cq0Hvv4ddGRuM= -github.com/dolthub/maphash v0.0.0-20221220182448-74e1e1ea1577 h1:SegEguMxToBn045KRHLIUlF2/jR7Y2qD6fF+3tdOfvI= -github.com/dolthub/maphash v0.0.0-20221220182448-74e1e1ea1577/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4= -github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9XGFa6q5Ap4Z/OhNkAMBaK5YeuEzwJt+NZdhiE= -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-20230531182027-fe0363298c52 h1:MGNJQpIOGRxtcKEsmbuMXFhMIJdlfxeeBaDZjbI6ZAg= -github.com/dolthub/vitess v0.0.0-20230531182027-fe0363298c52/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI= -github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ= -github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= -github.com/go-fonts/latin-modern v0.2.0 h1:5/Tv1Ek/QCr20C6ZOz15vw3g7GELYL98KWr8Hgo+3vk= -github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= -github.com/go-fonts/liberation v0.2.0 h1:jAkAWJP4S+OsrPLZM4/eC9iW7CtHy+HBXrEwZXWo5VM= -github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= -github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/gocraft/dbr/v2 v2.7.2 h1:ccUxMuz6RdZvD7VPhMRRMSS/ECF3gytPhPtcavjktHk= -github.com/gocraft/dbr/v2 v2.7.2/go.mod h1:5bCqyIXO5fYn3jEp/L06QF4K1siFdhxChMjdNu6YJrg= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v0.0.0-20180228145832-27454136f036/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= -github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/iancoleman/strcase v0.1.3/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jcmturner/gofork v0.0.0-20180107083740-2aebee971930/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= -github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d h1:c93kUJDtVAXFEhsCh5jSxyOJmFHuzcihnslQiX8Urwo= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6 h1:l6Y3mFnF46A+CeZsTrT8kVIuhayq1266oxWpDKE7hnQ= -github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6/go.mod h1:UtDV9qK925GVmbdjR+e1unqoo+wGWNHHC6XB1Eu6wpE= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I= -github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= -github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= -github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E= -github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/lyft/protoc-gen-star v0.5.2/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= -github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= -github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= -github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= -github.com/ncw/swift v1.0.52/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= -github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4/v4 v4.1.6 h1:ueMTcBBFrbT8K4uGDNNZPa8Z7LtPV7Cl0TDjaeHxP44= -github.com/pierrec/lz4/v4 v4.1.6/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug= -github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= -github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= -github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil/v3 v3.22.1 h1:33y31Q8J32+KstqPfscvFwBlNJ6xLaBy4xqBXzlYV5w= -github.com/shirou/gopsutil/v3 v3.22.1/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= -github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6 h1:31fhvQj+O9qDqMxUgQDOCQA5RV1iIFMzYPhBUyzg2p0= -github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6/go.mod h1:jk5gVE20+MCoyJ2TFiiMrbWPyaH4t9T5F3HwVdthB2w= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE= -github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM= -github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= -github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= -github.com/thepudds/swisstable v0.0.0-20221011152303-9c77dc657777 h1:5u+6YWU2faS+Sr/x8j9yalMpSDUkatNOZWXV3wMUCGQ= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= -github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= -github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= -github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vbauerster/mpb v3.4.0+incompatible h1:mfiiYw87ARaeRW6x5gWwYRUawxaW1tLAD8IceomUCNw= -github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU= -github.com/vbauerster/mpb/v8 v8.0.2 h1:alVQG69Jg5+Ku9Hu1dakDx50uACEHnIzS7i356NQ/Vs= -github.com/vbauerster/mpb/v8 v8.0.2/go.mod h1:Z9VJYIzXls7xZwirZjShGsi+14enzJhQfGyb/XZK0ZQ= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xitongsys/parquet-go v1.5.1/go.mod h1:xUxwM8ELydxh4edHGegYq1pA8NnMKDx0K/GyB0o2bww= -github.com/xitongsys/parquet-go v1.6.1 h1:F1snhlfL5U1hC1yE7Op8qLWFIZEzqmM46pCEspu9OC0= -github.com/xitongsys/parquet-go v1.6.1/go.mod h1:oNMMTE7vxZkSeV4Y6Q+DSpnR50DdpFM6Jx2CRav1OHI= -github.com/xitongsys/parquet-go-source v0.0.0-20190524061010-2b72cbee77d5/go.mod h1:xxCx7Wpym/3QCo6JhujJX51dzSXrwmb0oH6FQb39SEA= -github.com/xitongsys/parquet-go-source v0.0.0-20200817004010-026bad9b25d0/go.mod h1:HYhIKsdns7xz80OgkbgJYrtQY7FjHWHKH6cvN7+czGE= -github.com/xitongsys/parquet-go-source v0.0.0-20211010230925-397910c5e371 h1:RfGiOP/lWKBeNgpXmCeandYGV4pAnZsl42kX50p1UgE= -github.com/xitongsys/parquet-go-source v0.0.0-20211010230925-397910c5e371/go.mod h1:qLb2Itmdcp7KPa5KZKvhE9U1q5bYSOmgeOckF/H2rQA= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= -github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= -github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= -github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= -go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= -go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= -go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= -golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -gonum.org/v1/plot v0.11.0 h1:z2ZkgNqW34d0oYUzd80RRlc0L9kWtenqK4kflZG1lGc= -gonum.org/v1/plot v0.11.0/go.mod h1:fH9YnKnDKax0u5EzHVXvhN5HJwtMFWIOLNuhgUahbCQ= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo= -google.golang.org/api v0.32.0 h1:Le77IccnTqEa8ryp9wIpX5W3zYm7Gf9LhOp9PHcwFts= -google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200622133129-d0ee0c36e670/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= -google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc= -gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.66.0 h1:DZeAkuQGQqnm9Xv36SbMJEU8aFBz4wL04UpMWPWwjzg= +cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.12.0 h1:4y3gHptW1EHVtcPAVE0eBBlFuGqEejTTG3KdIE0lUX4= +cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +git.sr.ht/~sbinet/gg v0.3.1 h1:LNhjNn8DerC8f9DHLz6lS0YYul/b602DUxDgGkd/Aik= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= +github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc= +github.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8= +github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible h1:QoRMR0TCctLDqBCMyOu1eXdZyMw3F7uGA9qPn2J4+R8= +github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.0.0-20181112125854-24918abba929/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714 h1:Jz3KVLYY5+JO7rDiX0sAuRGtuv2vG01r17Y9nLMWNUw= +github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/attic-labs/kingpin v2.2.7-0.20180312050558-442efcfac769+incompatible h1:wd5mq8xSfwCYd1JpQ309s+3tTlP/gifcG2awOA3x5Vk= +github.com/attic-labs/kingpin v2.2.7-0.20180312050558-442efcfac769+incompatible/go.mod h1:Cp18FeDCvsK+cD2QAGkqerGjrgSXLiJWnjHeY2mneBc= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.30.19/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.34.0 h1:brux2dRrlwCF5JhTL7MUT3WUwo9zfDHZZp3+g3Mvlmo= +github.com/aws/aws-sdk-go v1.34.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= +github.com/aws/aws-sdk-go-v2/config v1.5.0/go.mod h1:RWlPOAW3E3tbtNAqTwvSW54Of/yP3oiZXMI0xfUdjyA= +github.com/aws/aws-sdk-go-v2/credentials v1.3.1/go.mod h1:r0n73xwsIVagq8RsxmZbGSRQFj9As3je72C2WzUIToc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.3.0/go.mod h1:2LAuqPx1I6jNfaGDucWfA2zqQCYCOMCDHiCOciALyNw= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.3.2/go.mod h1:qaqQiHSrOUVOfKe6fhgQ6UzhxjwqVW8aHNegd6Ws4w4= +github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1/go.mod h1:Zy8smImhTdOETZqfyn01iNOe0CNggVbPjCajyaz6Gvg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.1/go.mod h1:v33JQ57i2nekYTA70Mb+O18KeH4KqhdqxTJZNK1zdRE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.1/go.mod h1:zceowr5Z1Nh2WVP8bf/3ikB41IZW59E4yIYbg+pC6mw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.1/go.mod h1:6EQZIwNNvHpq/2/QSJnp4+ECvqIy55w95Ofs0ze+nGQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.11.1/go.mod h1:XLAGFrEjbvMCLvAtWLLP32yTv8GpBquCApZEycDLunI= +github.com/aws/aws-sdk-go-v2/service/sso v1.3.1/go.mod h1:J3A3RGUvuCZjvSuZEcOpHDnzZP/sKbhDWV2T1EOzFIM= +github.com/aws/aws-sdk-go-v2/service/sts v1.6.0/go.mod h1:q7o0j7d7HrJk/vr9uUt3BVRASvcU7gYZB9PUgPiByXg= +github.com/aws/smithy-go v1.6.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/bcicen/jstream v1.0.0 h1:gOi+Sn9mHrpePlENynPKA6Dra/PjLaIpqrTevhfvLAA= +github.com/bcicen/jstream v1.0.0/go.mod h1:9ielPxqFry7Y4Tg3j4BfjPocfJ3TbsRtXOAYXYmRuAQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/colinmarc/hdfs/v2 v2.1.1/go.mod h1:M3x+k8UKKmxtFu++uAZ0OtDU8jR3jnaZIAc6yK4Ue0c= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creasty/defaults v1.6.0 h1:ltuE9cfphUtlrBeomuu8PEyISTXnxqkBIoQfXgv7BSc= +github.com/creasty/defaults v1.6.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= +github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= +github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= +github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1Gms9599cr0REMww= +github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2/go.mod h1:mIEZOHnFx4ZMQeawhw9rhsj+0zwQj7adVsnBX7t+eKY= +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-20230524105445-af7e7991c97e h1:kPsT4a47cw1+y/N5SSCkma7FhAPw7KeGmD6c9PBZW9Y= +github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168= +github.com/dolthub/go-mysql-server v0.15.1-0.20230602200348-162f21795cab h1:+xeaazQ4jDIx0+Fo7MdmEfg/I5xjuDrO576zdfnGjlA= +github.com/dolthub/go-mysql-server v0.15.1-0.20230602200348-162f21795cab/go.mod h1:uXHw3YMx/PLUe5vUaFDdr66lVHiabnn0xi1LZg3T+FA= +github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= +github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto= +github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72 h1:NfWmngMi1CYUWU4Ix8wM+USEhjc+mhPlT9JUR/anvbQ= +github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72/go.mod h1:ZWUdY4iszqRQ8OcoXClkxiAVAoWoK3cq0Hvv4ddGRuM= +github.com/dolthub/maphash v0.0.0-20221220182448-74e1e1ea1577 h1:SegEguMxToBn045KRHLIUlF2/jR7Y2qD6fF+3tdOfvI= +github.com/dolthub/maphash v0.0.0-20221220182448-74e1e1ea1577/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4= +github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9XGFa6q5Ap4Z/OhNkAMBaK5YeuEzwJt+NZdhiE= +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-20230531182027-fe0363298c52 h1:MGNJQpIOGRxtcKEsmbuMXFhMIJdlfxeeBaDZjbI6ZAg= +github.com/dolthub/vitess v0.0.0-20230531182027-fe0363298c52/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI= +github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0 h1:5/Tv1Ek/QCr20C6ZOz15vw3g7GELYL98KWr8Hgo+3vk= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.2.0 h1:jAkAWJP4S+OsrPLZM4/eC9iW7CtHy+HBXrEwZXWo5VM= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gocraft/dbr/v2 v2.7.2 h1:ccUxMuz6RdZvD7VPhMRRMSS/ECF3gytPhPtcavjktHk= +github.com/gocraft/dbr/v2 v2.7.2/go.mod h1:5bCqyIXO5fYn3jEp/L06QF4K1siFdhxChMjdNu6YJrg= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v0.0.0-20180228145832-27454136f036/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/iancoleman/strcase v0.1.3/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jcmturner/gofork v0.0.0-20180107083740-2aebee971930/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= +github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d h1:c93kUJDtVAXFEhsCh5jSxyOJmFHuzcihnslQiX8Urwo= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6 h1:l6Y3mFnF46A+CeZsTrT8kVIuhayq1266oxWpDKE7hnQ= +github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6/go.mod h1:UtDV9qK925GVmbdjR+e1unqoo+wGWNHHC6XB1Eu6wpE= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I= +github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= +github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= +github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E= +github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lyft/protoc-gen-star v0.5.2/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= +github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= +github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/ncw/swift v1.0.52/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.6 h1:ueMTcBBFrbT8K4uGDNNZPa8Z7LtPV7Cl0TDjaeHxP44= +github.com/pierrec/lz4/v4 v4.1.6/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug= +github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil/v3 v3.22.1 h1:33y31Q8J32+KstqPfscvFwBlNJ6xLaBy4xqBXzlYV5w= +github.com/shirou/gopsutil/v3 v3.22.1/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6 h1:31fhvQj+O9qDqMxUgQDOCQA5RV1iIFMzYPhBUyzg2p0= +github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6/go.mod h1:jk5gVE20+MCoyJ2TFiiMrbWPyaH4t9T5F3HwVdthB2w= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE= +github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM= +github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ= +github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +github.com/thepudds/swisstable v0.0.0-20221011152303-9c77dc657777 h1:5u+6YWU2faS+Sr/x8j9yalMpSDUkatNOZWXV3wMUCGQ= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= +github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= +github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= +github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vbauerster/mpb v3.4.0+incompatible h1:mfiiYw87ARaeRW6x5gWwYRUawxaW1tLAD8IceomUCNw= +github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU= +github.com/vbauerster/mpb/v8 v8.0.2 h1:alVQG69Jg5+Ku9Hu1dakDx50uACEHnIzS7i356NQ/Vs= +github.com/vbauerster/mpb/v8 v8.0.2/go.mod h1:Z9VJYIzXls7xZwirZjShGsi+14enzJhQfGyb/XZK0ZQ= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xitongsys/parquet-go v1.5.1/go.mod h1:xUxwM8ELydxh4edHGegYq1pA8NnMKDx0K/GyB0o2bww= +github.com/xitongsys/parquet-go v1.6.1 h1:F1snhlfL5U1hC1yE7Op8qLWFIZEzqmM46pCEspu9OC0= +github.com/xitongsys/parquet-go v1.6.1/go.mod h1:oNMMTE7vxZkSeV4Y6Q+DSpnR50DdpFM6Jx2CRav1OHI= +github.com/xitongsys/parquet-go-source v0.0.0-20190524061010-2b72cbee77d5/go.mod h1:xxCx7Wpym/3QCo6JhujJX51dzSXrwmb0oH6FQb39SEA= +github.com/xitongsys/parquet-go-source v0.0.0-20200817004010-026bad9b25d0/go.mod h1:HYhIKsdns7xz80OgkbgJYrtQY7FjHWHKH6cvN7+czGE= +github.com/xitongsys/parquet-go-source v0.0.0-20211010230925-397910c5e371 h1:RfGiOP/lWKBeNgpXmCeandYGV4pAnZsl42kX50p1UgE= +github.com/xitongsys/parquet-go-source v0.0.0-20211010230925-397910c5e371/go.mod h1:qLb2Itmdcp7KPa5KZKvhE9U1q5bYSOmgeOckF/H2rQA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= +github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= +go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= +go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= +go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= +golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.11.0 h1:z2ZkgNqW34d0oYUzd80RRlc0L9kWtenqK4kflZG1lGc= +gonum.org/v1/plot v0.11.0/go.mod h1:fH9YnKnDKax0u5EzHVXvhN5HJwtMFWIOLNuhgUahbCQ= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo= +google.golang.org/api v0.32.0 h1:Le77IccnTqEa8ryp9wIpX5W3zYm7Gf9LhOp9PHcwFts= +google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200622133129-d0ee0c36e670/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc= +gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 07e3cbd1a7c92e0f41686554097ddf859aec1f06 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 13:35:07 -0700 Subject: [PATCH 137/167] Fix test provider --- go/libraries/doltcore/sqle/dsess/dolt_session_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/libraries/doltcore/sqle/dsess/dolt_session_test.go b/go/libraries/doltcore/sqle/dsess/dolt_session_test.go index 805237c5ec..8b3fd1f923 100644 --- a/go/libraries/doltcore/sqle/dsess/dolt_session_test.go +++ b/go/libraries/doltcore/sqle/dsess/dolt_session_test.go @@ -251,6 +251,10 @@ type emptyRevisionDatabaseProvider struct { sql.DatabaseProvider } +func (e emptyRevisionDatabaseProvider) BaseDatabase(ctx *sql.Context, dbName string) (SqlDatabase, bool) { + return nil, false +} + func (e emptyRevisionDatabaseProvider) SessionDatabase(ctx *sql.Context, dbName string) (SqlDatabase, bool, error) { return nil, false, sql.ErrDatabaseNotFound.New(dbName) } From 783ba4a1f8ec56a2d29f61d797c9daae2fcb1e9f Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 13:43:11 -0700 Subject: [PATCH 138/167] Update skipped counter --- go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 8fa01edff5..475a0c505e 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -49,7 +49,7 @@ var skipPrepared bool // SkipPreparedsCount is used by the "ci-check-repo CI workflow // as a reminder to consider prepareds when adding a new // enginetest suite. -const SkipPreparedsCount = 85 +const SkipPreparedsCount = 87 const skipPreparedFlag = "DOLT_SKIP_PREPARED_ENGINETESTS" From aff1c0aa5f42e705c48f583533982a06caaf0802 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Fri, 2 Jun 2023 13:54:18 -0700 Subject: [PATCH 139/167] Stupid skip check --- go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 475a0c505e..ed584fc010 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -49,7 +49,7 @@ var skipPrepared bool // SkipPreparedsCount is used by the "ci-check-repo CI workflow // as a reminder to consider prepareds when adding a new // enginetest suite. -const SkipPreparedsCount = 87 +const SkipPreparedsCount = 83 const skipPreparedFlag = "DOLT_SKIP_PREPARED_ENGINETESTS" From 79d1e56a61e8bbc3ba2394a92f98aa1a020ac766 Mon Sep 17 00:00:00 2001 From: zachmu Date: Fri, 2 Jun 2023 21:03:36 +0000 Subject: [PATCH 140/167] [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh --- go/libraries/doltcore/sqle/database.go | 2 +- .../doltcore/sqle/database_provider.go | 10 +- .../doltcore/sqle/dprocedures/dolt_branch.go | 4 +- .../doltcore/sqle/dsess/branch_control.go | 4 +- go/libraries/doltcore/sqle/dsess/session.go | 37 +++-- go/libraries/doltcore/sqle/dsess/variables.go | 2 +- .../sqle/enginetest/branch_control_test.go | 20 +-- .../sqle/enginetest/dolt_branch_queries.go | 70 ++++----- .../sqle/enginetest/dolt_engine_test.go | 26 ++-- .../sqle/enginetest/dolt_queries_merge.go | 6 +- .../sqle/enginetest/dolt_server_test.go | 2 +- .../enginetest/dolt_transaction_queries.go | 32 ++-- .../sqle/enginetest/privilege_test.go | 144 +++++++++--------- 13 files changed, 179 insertions(+), 180 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 27add579c1..924e8e7210 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -147,7 +147,7 @@ func (db Database) Name() string { } // AliasedName is what allows databases named e.g. `mydb/b1` to work with the grant and info schema tables that expect -// a base (no revision qualifier) db name +// a base (no revision qualifier) db name func (db Database) AliasedName() string { return db.baseName } diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index c864462823..6f872b00a5 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -172,7 +172,7 @@ func (p DoltDatabaseProvider) FileSystemForDatabase(dbname string) (filesys.File defer p.mu.Unlock() baseName, _ := dsess.SplitRevisionDbName(dbname) - + dbLocation, ok := p.dbLocations[strings.ToLower(baseName)] if !ok { return nil, sql.ErrDatabaseNotFound.New(dbname) @@ -259,14 +259,14 @@ func (p DoltDatabaseProvider) HasDatabase(ctx *sql.Context, name string) bool { func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database) { currentDb := ctx.GetCurrentDatabase() currBase, currRev := dsess.SplitRevisionDbName(currentDb) - + p.mu.RLock() showBranches, _ := dsess.GetBooleanSystemVar(ctx, dsess.ShowBranchDatabases) all = make([]sql.Database, 0, len(p.databases)) for _, db := range p.databases { base, _ := dsess.SplitRevisionDbName(db.Name()) - + // If there's a revision database in use, swap that one in for its base db, but keep the same name if currRev != "" && strings.ToLower(currBase) == strings.ToLower(base) { rdb, ok, err := p.databaseForRevision(ctx, currentDb, currBase) @@ -1041,7 +1041,7 @@ func (p DoltDatabaseProvider) BaseDatabase(ctx *sql.Context, name string) (dsess db, ok := p.databases[strings.ToLower(baseName)] p.mu.RUnlock() - return db, ok + return db, ok } // SessionDatabase implements dsess.SessionDatabaseProvider @@ -1283,7 +1283,7 @@ func revisionDbForBranch(ctx context.Context, srcDb dsess.SqlDatabase, revSpec s RepoStateWriter: srcDb.DbData().Rsw, RepoStateReader: srcDb.DbData().Rsr, } - + baseName, _ := dsess.SplitRevisionDbName(srcDb.Name()) // TODO: we need a base name method here diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go index fefd359aea..c5e98c7e62 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_branch.go @@ -93,7 +93,7 @@ func commitTransaction(ctx *sql.Context, dSess *dsess.DoltSession, rsc *doltdb.R if rsc != nil { dsess.WaitForReplicationController(ctx, *rsc) } - + return nil } @@ -222,7 +222,7 @@ func validateBranchNotActiveInAnySession(ctx *sql.Context, branchName string) er if currentDbName == "" { return nil } - + if sqlserver.RunningInServerMode() == false { return nil } diff --git a/go/libraries/doltcore/sqle/dsess/branch_control.go b/go/libraries/doltcore/sqle/dsess/branch_control.go index ef0c94eafd..c878065896 100755 --- a/go/libraries/doltcore/sqle/dsess/branch_control.go +++ b/go/libraries/doltcore/sqle/dsess/branch_control.go @@ -21,8 +21,8 @@ import ( ) // CheckAccessForDb checks whether the current user has the given permissions for the given database. -// This has to live here, rather than in the branch_control package, to prevent a dependency cycle with that package. -// We could also avoid this by defining branchController as an interface used by dsess. +// This has to live here, rather than in the branch_control package, to prevent a dependency cycle with that package. +// We could also avoid this by defining branchController as an interface used by dsess. func CheckAccessForDb(ctx context.Context, db SqlDatabase, flags branch_control.Permissions) error { branchAwareSession := branch_control.GetBranchAwareSession(ctx) // A nil session means we're not in the SQL context, so we allow all operations diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index f25f1e69f8..747904005c 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -373,20 +373,20 @@ func (d *DoltSession) newWorkingSetForHead(ctx *sql.Context, wsRef ref.WorkingSe return doltdb.EmptyWorkingSet(wsRef).WithWorkingRoot(headRoot).WithStagedRoot(headRoot), nil } -// CommitTransaction commits the in-progress transaction. Depending on session settings, this may write only a new -// working set, or may additionally create a new dolt commit for the current HEAD. If more than one branch head has +// CommitTransaction commits the in-progress transaction. Depending on session settings, this may write only a new +// working set, or may additionally create a new dolt commit for the current HEAD. If more than one branch head has // changes, the transaction is rejected. func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) (err error) { - // Any non-error path must set the ctx's transaction to nil even if no work was done, because the engine only clears - // out transaction state in some cases. Changes to only branch heads (creating a new branch, reset, etc.) have no + // Any non-error path must set the ctx's transaction to nil even if no work was done, because the engine only clears + // out transaction state in some cases. Changes to only branch heads (creating a new branch, reset, etc.) have no // changes to commit visible to the transaction logic, but they still need a new transaction on the next statement. - // See comment in |commitBranchState| + // See comment in |commitBranchState| defer func() { if err == nil { ctx.SetTransaction(nil) } }() - + if d.BatchMode() == Batched { for _, db := range d.provider.DoltDatabases() { err = d.Flush(ctx, db.Name()) @@ -459,7 +459,7 @@ func (d *DoltSession) validateDoltCommit(ctx *sql.Context, dirtyBranchState *bra } currDbBaseName, _ := SplitRevisionDbName(currDb) dirtyDbBaseName, _ := SplitRevisionDbName(dirtyBranchState.dbState.dbName) - + if strings.ToLower(currDbBaseName) != strings.ToLower(dirtyDbBaseName) { return fmt.Errorf("no changes to dolt_commit on database %s", currDbBaseName) } @@ -479,7 +479,7 @@ func (d *DoltSession) validateDoltCommit(ctx *sql.Context, dirtyBranchState *bra if dbState.currRevSpec != dirtyBranch.GetPath() { return fmt.Errorf("no changes to dolt_commit on branch %s", dbState.currRevSpec) } - + return nil } @@ -566,7 +566,7 @@ func (d *DoltSession) commitBranchState( if err != nil { return nil, err } - + // Anything that commits a transaction needs its current transaction state cleared so that the next statement starts // a new transaction. This should in principle be done by the engine, but it currently only understands explicit // COMMIT statements. Any other statements that commit a transaction, including stored procedures, needs to do this @@ -959,9 +959,9 @@ func (d *DoltSession) SwitchWorkingSet( if !ok { return sql.ErrDatabaseNotFound.New(dbName) } - + ctx.SetCurrentDatabase(baseName) - + return nil } @@ -1114,7 +1114,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { baseName, _ := SplitRevisionDbName(revisionQualifiedName) DefineSystemVariablesForDB(baseName) - + // TODO: odd that we need to tell the DB what its own revision is here dbState, err := db.InitialDBState(ctx, db.Revision()) if err != nil { @@ -1137,21 +1137,21 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } sessionState.dbName = baseName - + baseDb, ok := d.provider.BaseDatabase(ctx, baseName) if !ok { d.mu.Unlock() return fmt.Errorf("unable to find database %s, this is a bug", baseName) } - - // The checkedOutRevSpec should be the checked out branch of the database if available, or the revision + + // The checkedOutRevSpec should be the checked out branch of the database if available, or the revision // string otherwise sessionState.checkedOutRevSpec, err = DefaultHead(baseName, baseDb) if err != nil { d.mu.Unlock() return err } - + sessionState.currRevType = db.RevisionType() sessionState.currRevSpec = db.Revision() } @@ -1666,11 +1666,10 @@ func DefaultHead(baseName string, db SqlDatabase) (string, error) { head = headRef.GetPath() } } - + if head == "" { head = db.Revision() } - + return head, nil } - diff --git a/go/libraries/doltcore/sqle/dsess/variables.go b/go/libraries/doltcore/sqle/dsess/variables.go index 82baf1f5d5..033aace245 100644 --- a/go/libraries/doltcore/sqle/dsess/variables.go +++ b/go/libraries/doltcore/sqle/dsess/variables.go @@ -62,7 +62,7 @@ const URLTemplateDatabasePlaceholder = "{database}" // DefineSystemVariablesForDB defines per database dolt-session variables in the engine as necessary func DefineSystemVariablesForDB(name string) { name, _ = SplitRevisionDbName(name) - + if _, _, ok := sql.SystemVariables.GetGlobal(name + HeadKeySuffix); !ok { sql.SystemVariables.AddSystemVariables([]sql.SystemVariable{ { diff --git a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go index eeedc572cf..99b666361f 100644 --- a/go/libraries/doltcore/sqle/enginetest/branch_control_test.go +++ b/go/libraries/doltcore/sqle/enginetest/branch_control_test.go @@ -1422,14 +1422,14 @@ func TestBranchControlBlocks(t *testing.T) { if test.SkipMessage != "" { t.Skip(test.SkipMessage) } - + harness := newDoltHarness(t) defer harness.Close() - + engine, err := harness.NewEngine(t) require.NoError(t, err) defer engine.Close() - + rootCtx := enginetest.NewContext(harness) rootCtx.NewCtxWithClient(sql.Client{ User: "root", @@ -1437,21 +1437,21 @@ func TestBranchControlBlocks(t *testing.T) { }) engine.Analyzer.Catalog.MySQLDb.AddRootAccount() engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) - + for _, statement := range append(TestUserSetUpScripts, test.SetUpScript...) { enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) } - + userCtx := enginetest.NewContextWithClient(harness, sql.Client{ User: "testuser", Address: "localhost", }) enginetest.AssertErrWithCtx(t, engine, harness, userCtx, test.Query, test.ExpectedErr) - + addUserQuery := "INSERT INTO dolt_branch_control VALUES ('%', 'main', 'testuser', 'localhost', 'write'), ('%', 'other', 'testuser', 'localhost', 'write');" addUserQueryResults := []sql.Row{{types.NewOkResult(2)}} enginetest.TestQueryWithContext(t, rootCtx, engine, harness, addUserQuery, addUserQueryResults, nil, nil) - + sch, iter, err := engine.Query(userCtx, test.Query) if err == nil { _, err = sql.RowIterToRows(userCtx, sch, iter) @@ -1462,14 +1462,14 @@ func TestBranchControlBlocks(t *testing.T) { // These tests are run with permission on main but not other for _, test := range BranchControlOtherDbBlockTests { - t.Run("OtherDB_" + test.Name, func(t *testing.T) { + t.Run("OtherDB_"+test.Name, func(t *testing.T) { if test.SkipMessage != "" { t.Skip(test.SkipMessage) } harness := newDoltHarness(t) defer harness.Close() - + engine, err := harness.NewEngine(t) require.NoError(t, err) defer engine.Close() @@ -1481,7 +1481,7 @@ func TestBranchControlBlocks(t *testing.T) { }) engine.Analyzer.Catalog.MySQLDb.AddRootAccount() engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) - + for _, statement := range append(TestUserSetUpScripts, test.SetUpScript...) { enginetest.RunQueryWithContext(t, engine, harness, rootCtx, statement) } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go index 8c7b3aac2c..119b2b86ce 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_branch_queries.go @@ -188,7 +188,7 @@ var ViewBranchTests = []queries.ScriptTest{ SkipResultsCheck: true, }, { - Query: "select * from v1", + Query: "select * from v1", ExpectedErr: sql.ErrTableNotFound, }, { @@ -214,21 +214,21 @@ var ViewBranchTests = []queries.ScriptTest{ { Query: "select * from v1", Expected: []sql.Row{{3, 3}}, - Skip: true, // https://github.com/dolthub/dolt/issues/6078 + Skip: true, // https://github.com/dolthub/dolt/issues/6078 }, { Query: "use mydb/main", SkipResultsCheck: true, }, { - Query: "select * from v1", + Query: "select * from v1", ExpectedErr: sql.ErrTableNotFound, - Skip: true, // https://github.com/dolthub/dolt/issues/6078 + Skip: true, // https://github.com/dolthub/dolt/issues/6078 }, { Query: "select * from `mydb/b1`.v1", Expected: []sql.Row{{3, 3}}, - Skip: true, // https://github.com/dolthub/dolt/issues/6078 + Skip: true, // https://github.com/dolthub/dolt/issues/6078 }, }, }, @@ -260,7 +260,7 @@ var DdlBranchTests = []queries.ScriptTest{ SkipResultsCheck: true, }, { - Query: "select * from t2", + Query: "select * from t2", ExpectedErr: sql.ErrTableNotFound, }, { @@ -293,7 +293,7 @@ var DdlBranchTests = []queries.ScriptTest{ SkipResultsCheck: true, }, { - Query: "select * from t2", + Query: "select * from t2", ExpectedErr: sql.ErrTableNotFound, }, { @@ -328,7 +328,7 @@ var DdlBranchTests = []queries.ScriptTest{ SkipResultsCheck: true, }, { - Query: "select * from t2", + Query: "select * from t2", ExpectedErr: sql.ErrTableNotFound, }, { @@ -420,7 +420,7 @@ var DdlBranchTests = []queries.ScriptTest{ Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, }, { - Query: "show create table `mydb/b1`.t1", + Query: "show create table `mydb/b1`.t1", Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + " `a` int NOT NULL,\n" + " `b` int,\n" + @@ -429,24 +429,24 @@ var DdlBranchTests = []queries.ScriptTest{ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "show create table t1", + Query: "show create table t1", Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + - " `a` int NOT NULL,\n" + - " `b` int,\n" + - " PRIMARY KEY (`a`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { Query: "alter table `mydb/b1`.t1 drop index idx", Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}}, }, { - Query: "show create table `mydb/b1`.t1", + Query: "show create table `mydb/b1`.t1", Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + - " `a` int NOT NULL,\n" + - " `b` int,\n" + - " PRIMARY KEY (`a`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, }, }, @@ -464,7 +464,7 @@ var DdlBranchTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "show create table `mydb/b1`.t1", + Query: "show create table `mydb/b1`.t1", Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + " `a` int NOT NULL,\n" + " `b` int,\n" + @@ -473,16 +473,16 @@ var DdlBranchTests = []queries.ScriptTest{ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { - Query: "insert into `mydb/b1`.t1 values (4, 4)", + Query: "insert into `mydb/b1`.t1 values (4, 4)", ExpectedErr: sql.ErrCheckConstraintViolated, - }, + }, { - Query: "show create table t1", + Query: "show create table t1", Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + - " `a` int NOT NULL,\n" + - " `b` int,\n" + - " PRIMARY KEY (`a`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, { Query: "insert into t1 values (4, 4)", @@ -493,12 +493,12 @@ var DdlBranchTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "show create table `mydb/b1`.t1", + Query: "show create table `mydb/b1`.t1", Expected: []sql.Row{{"t1", "CREATE TABLE `t1` (\n" + - " `a` int NOT NULL,\n" + - " `b` int,\n" + - " PRIMARY KEY (`a`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + " `a` int NOT NULL,\n" + + " `b` int,\n" + + " PRIMARY KEY (`a`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, }, }, }, @@ -514,7 +514,7 @@ var BranchPlanTests = []queries.ScriptTest{ "call dolt_branch('b1')", "use mydb/b1", "create index idx on t1 (b)", - }, + }, Assertions: []queries.ScriptTestAssertion{ { Query: "explain select * from t1 where b = 1", @@ -526,7 +526,7 @@ var BranchPlanTests = []queries.ScriptTest{ }, }, { - Query: "use mydb/main", + Query: "use mydb/main", SkipResultsCheck: true, }, { @@ -588,7 +588,7 @@ var BranchPlanTests = []queries.ScriptTest{ }, }, { - Query: "use mydb/main", + Query: "use mydb/main", SkipResultsCheck: true, }, { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index ed584fc010..ee88e4cd61 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -117,7 +117,7 @@ func TestSingleQuery(t *testing.T) { func TestSingleScript(t *testing.T) { // t.Skip() - var script = queries.ScriptTest { + var script = queries.ScriptTest{ Name: "committing to another branch on another database with dolt_transaction_commit", SetUpScript: []string{ "create table t1 (a int)", @@ -137,7 +137,7 @@ func TestSingleScript(t *testing.T) { }, Assertions: []queries.ScriptTestAssertion{ { - Query: "insert into `db1/b1`.t1 values (1)", + Query: "insert into `db1/b1`.t1 values (1)", ExpectedErrStr: "no changes to dolt_commit on database mydb", }, }, @@ -918,14 +918,14 @@ func TestForeignKeys(t *testing.T) { } func TestForeignKeyBranches(t *testing.T) { - setupPrefix := []string { + setupPrefix := []string{ "call dolt_branch('b1')", "use mydb/b1", } - assertionsPrefix := []queries.ScriptTestAssertion { + assertionsPrefix := []queries.ScriptTestAssertion{ { - Query: "use mydb/b1", - SkipResultsCheck: true, + Query: "use mydb/b1", + SkipResultsCheck: true, }, } for _, script := range queries.ForeignKeyTests { @@ -937,7 +937,7 @@ func TestForeignKeyBranches(t *testing.T) { modifiedScript.Assertions = append(assertionsPrefix, modifiedScript.Assertions...) enginetest.TestScript(t, h, modifiedScript) } - + for _, script := range ForeignKeyBranchTests { // New harness for every script because we create branches h := newDoltHarness(t) @@ -947,14 +947,14 @@ func TestForeignKeyBranches(t *testing.T) { } func TestForeignKeyBranchesPrepared(t *testing.T) { - setupPrefix := []string { + setupPrefix := []string{ "call dolt_branch('b1')", "use mydb/b1", } - assertionsPrefix := []queries.ScriptTestAssertion { + assertionsPrefix := []queries.ScriptTestAssertion{ { - Query: "use mydb/b1", - SkipResultsCheck: true, + Query: "use mydb/b1", + SkipResultsCheck: true, }, } for _, script := range queries.ForeignKeyTests { @@ -1468,7 +1468,7 @@ func TestViewsWithAsOfPrepared(t *testing.T) { func TestDoltMerge(t *testing.T) { for _, script := range MergeScripts { - // harness can't reset effectively when there are new commits / branches created, so use a new harness for + // harness can't reset effectively when there are new commits / branches created, so use a new harness for // each script func() { h := newDoltHarness(t).WithParallelism(1) @@ -1490,7 +1490,7 @@ func TestDoltMerge(t *testing.T) { func TestDoltMergePrepared(t *testing.T) { for _, script := range MergeScripts { - // harness can't reset effectively when there are new commits / branches created, so use a new harness for + // harness can't reset effectively when there are new commits / branches created, so use a new harness for // each script func() { h := newDoltHarness(t).WithParallelism(1) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index 2c753483e5..18d3e9272e 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -536,7 +536,7 @@ var MergeScripts = []queries.ScriptTest{ Expected: []sql.Row{{1}, {2}, {3}, {4}, {1000}}, }, { - Query: "use `mydb/main`", + Query: "use `mydb/main`", SkipResultsCheck: true, }, { @@ -672,7 +672,7 @@ var MergeScripts = []queries.ScriptTest{ }, }, { - Query: "use `mydb/feature-branch`", + Query: "use `mydb/feature-branch`", SkipResultsCheck: true, }, { @@ -1457,7 +1457,7 @@ var Dolt1MergeScripts = []queries.ScriptTest{ }, Assertions: []queries.ScriptTestAssertion{ { - Query: "insert into t values (-1)", + Query: "insert into t values (-1)", ExpectedErr: sql.ErrCheckConstraintViolated, }, { diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index 7f2031c363..17a3b14185 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -409,7 +409,7 @@ var DropDatabaseMultiSessionScriptTests = []queries.ScriptTest{ Expected: []sql.Row{{"db01/branch1"}}, }, { - Query: "/* client b */ show tables;", + Query: "/* client b */ show tables;", ExpectedErrStr: "Error 1105: database not found: db01/branch1", }, }, diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 778e80ef74..5796109543 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -2405,7 +2405,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ SkipResultsCheck: true, }, { - Query: "select * from t1 order by a", + Query: "select * from t1 order by a", Expected: []sql.Row{{1}}, }, }, @@ -2444,7 +2444,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "commit", + Query: "commit", ExpectedErrStr: "no changes to dolt_commit on branch main", }, { @@ -2484,7 +2484,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "call dolt_commit('-am', 'changes on b1')", + Query: "call dolt_commit('-am', 'changes on b1')", ExpectedErrStr: "nothing to commit", // this error is different from what you get with @@dolt_transaction_commit }, { @@ -2492,15 +2492,15 @@ var MultiDbTransactionTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "call dolt_commit('-am', 'other changes on b1')", + Query: "call dolt_commit('-am', 'other changes on b1')", SkipResultsCheck: true, }, { - Query: "select * from t1 order by a", + Query: "select * from t1 order by a", Expected: []sql.Row{{1}}, }, { - Query: "select message from dolt_log order by date desc limit 1", + Query: "select message from dolt_log order by date desc limit 1", Expected: []sql.Row{{"other changes on b1"}}, }, }, @@ -2517,7 +2517,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, Assertions: []queries.ScriptTestAssertion{ { - Query: "insert into `mydb/b1`.t1 values (1)", + Query: "insert into `mydb/b1`.t1 values (1)", ExpectedErrStr: "no changes to dolt_commit on branch main", }, { @@ -2531,7 +2531,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "commit", + Query: "commit", Expected: []sql.Row{}, }, { @@ -2699,11 +2699,11 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, Assertions: []queries.ScriptTestAssertion{ { - Query: "insert into `db1/b1`.t1 values (1)", + Query: "insert into `db1/b1`.t1 values (1)", Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}}, }, { - Query: "call dolt_commit('-am', 'changes on b1')", + Query: "call dolt_commit('-am', 'changes on b1')", ExpectedErrStr: "nothing to commit", // this error is different from what you get with @@dolt_transaction_commit }, { @@ -2711,15 +2711,15 @@ var MultiDbTransactionTests = []queries.ScriptTest{ Expected: []sql.Row{}, }, { - Query: "call dolt_commit('-am', 'other changes on b1')", + Query: "call dolt_commit('-am', 'other changes on b1')", SkipResultsCheck: true, }, { - Query: "select * from t1 order by a", + Query: "select * from t1 order by a", Expected: []sql.Row{{1}}, }, { - Query: "select message from dolt_log order by date desc limit 1", + Query: "select message from dolt_log order by date desc limit 1", Expected: []sql.Row{{"other changes on b1"}}, }, }, @@ -2801,7 +2801,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, Assertions: []queries.ScriptTestAssertion{ { - Query: "insert into `db1/b1`.t1 values (1)", + Query: "insert into `db1/b1`.t1 values (1)", ExpectedErrStr: "no changes to dolt_commit on database mydb", }, }, @@ -2832,7 +2832,7 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, { - Query: "commit", + Query: "commit", ExpectedErrStr: "no changes to dolt_commit on database mydb", }, }, @@ -2926,4 +2926,4 @@ var MultiDbTransactionTests = []queries.ScriptTest{ }, }, }, -} \ No newline at end of file +} diff --git a/go/libraries/doltcore/sqle/enginetest/privilege_test.go b/go/libraries/doltcore/sqle/enginetest/privilege_test.go index 2d16d2c547..7baab9c43e 100755 --- a/go/libraries/doltcore/sqle/enginetest/privilege_test.go +++ b/go/libraries/doltcore/sqle/enginetest/privilege_test.go @@ -32,7 +32,7 @@ var revisionDatabasePrivsSetupPrefix = []string{ "use mydb/b1", } -// The subset of tests in priv_auth_queries.go to run with alternate branch logic. Not all of them are suitable +// The subset of tests in priv_auth_queries.go to run with alternate branch logic. Not all of them are suitable // because they use non-qualified database names in their queries var revisionDatabasePrivilegeScriptNames = []string{ "Binlog replication privileges", @@ -50,24 +50,24 @@ var revisionDatabasePrivilegeScriptNames = []string{ } // TestRevisionDatabasePrivileges is a spot-check of privilege checking on the original privilege test scripts, -// but with a revisioned database as the current db +// but with a revisioned database as the current db func TestRevisionDatabasePrivileges(t *testing.T) { testsToRun := make(map[string]bool) for _, name := range revisionDatabasePrivilegeScriptNames { testsToRun[name] = true } - + var scripts []queries.UserPrivilegeTest for _, script := range queries.UserPrivTests { if testsToRun[script.Name] { scripts = append(scripts, script) } } - + require.Equal(t, len(scripts), len(testsToRun), - "Error in test setup: one or more expected tests not found. " + - "Did the name of a test change?") - + "Error in test setup: one or more expected tests not found. "+ + "Did the name of a test change?") + for _, script := range scripts { harness := newDoltHarness(t) harness.Setup(setup.MydbData, setup.MytableData) @@ -82,14 +82,14 @@ func TestRevisionDatabasePrivileges(t *testing.T) { }) engine.Analyzer.Catalog.MySQLDb.AddRootAccount() engine.Analyzer.Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) - + for _, statement := range append(revisionDatabasePrivsSetupPrefix, script.SetUpScript...) { if harness.SkipQueryTest(statement) { t.Skip() } enginetest.RunQueryWithContext(t, engine, harness, ctx, statement) } - + for _, assertion := range script.Assertions { if harness.SkipQueryTest(assertion.Query) { t.Skipf("Skipping query %s", assertion.Query) @@ -399,20 +399,20 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "INSERT INTO test VALUES (4);", + User: "tester", + Host: "localhost", + Query: "INSERT INTO test VALUES (4);", ExpectedErr: sql.ErrPrivilegeCheckFailed, }, { - User: "tester", - Host: "localhost", - Query: "UPDATE test set pk = 4 where pk = 3;", + User: "tester", + Host: "localhost", + Query: "UPDATE test set pk = 4 where pk = 3;", Expected: []sql.Row{{types.OkResult{ RowsAffected: 1, - Info: plan.UpdateInfo{ - Matched: 1, - Updated: 1, + Info: plan.UpdateInfo{ + Matched: 1, + Updated: 1, }, }}}, }, @@ -454,15 +454,15 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "INSERT INTO test VALUES (4);", + User: "tester", + Host: "localhost", + Query: "INSERT INTO test VALUES (4);", ExpectedErr: sql.ErrPrivilegeCheckFailed, }, { User: "tester", Host: "localhost", - Query: "DELETE from test where pk = 3;", + Query: "DELETE from test where pk = 3;", Expected: []sql.Row{{types.NewOkResult(1)}}, }, { @@ -508,10 +508,10 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "show tables;", - Expected: []sql.Row{{"mytable"}, {"test"}, {"t2"}}, + User: "tester", + Host: "localhost", + Query: "show tables;", + Expected: []sql.Row{{"mytable"}, {"test"}, {"t2"}}, }, }, }, @@ -545,10 +545,10 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "show tables;", - Expected: []sql.Row{{"mytable"}}, + User: "tester", + Host: "localhost", + Query: "show tables;", + Expected: []sql.Row{{"mytable"}}, }, }, }, @@ -578,14 +578,14 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "tester", Host: "localhost", - Query: "ALTER TABLE test add column a int;", + Query: "ALTER TABLE test add column a int;", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "desc test;", - Expected: []sql.Row{ + User: "tester", + Host: "localhost", + Query: "desc test;", + Expected: []sql.Row{ {"pk", "bigint", "NO", "PRI", "NULL", ""}, {"a", "int", "YES", "", "NULL", ""}, }, @@ -630,14 +630,14 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "tester", Host: "localhost", - Query: "create index t1 on test(a) ;", + Query: "create index t1 on test(a) ;", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "desc test;", - Expected: []sql.Row{ + User: "tester", + Host: "localhost", + Query: "desc test;", + Expected: []sql.Row{ {"pk", "bigint", "NO", "PRI", "NULL", ""}, {"a", "int", "YES", "MUL", "NULL", ""}, }, @@ -649,8 +649,8 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", + User: "tester", + Host: "localhost", Query: "drop index t1 on test;", ExpectedErr: sql.ErrPrivilegeCheckFailed, }, @@ -663,14 +663,14 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "tester", Host: "localhost", - Query: "drop index t1 on test;", + Query: "drop index t1 on test;", Expected: []sql.Row{{types.NewOkResult(0)}}, }, { - User: "tester", - Host: "localhost", - Query: "desc test;", - Expected: []sql.Row{ + User: "tester", + Host: "localhost", + Query: "desc test;", + Expected: []sql.Row{ {"pk", "bigint", "NO", "PRI", "NULL", ""}, {"a", "int", "YES", "", "NULL", ""}, }, @@ -715,14 +715,14 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "tester", Host: "localhost", - Query: "alter table test add constraint chk1 CHECK (a < 10);", + Query: "alter table test add constraint chk1 CHECK (a < 10);", Expected: []sql.Row{}, }, { - User: "tester", - Host: "localhost", - Query: "show create table test;", - Expected: []sql.Row{ + User: "tester", + Host: "localhost", + Query: "show create table test;", + Expected: []sql.Row{ {"test", "CREATE TABLE `test` (\n" + " `pk` bigint NOT NULL,\n" + " `a` int,\n" + @@ -752,25 +752,25 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "tester", Host: "localhost", - Query: "alter table test drop check chk1;", + Query: "alter table test drop check chk1;", Expected: []sql.Row{}, }, { - User: "tester", - Host: "localhost", - Query: "show create table test;", - Expected: []sql.Row{ + User: "tester", + Host: "localhost", + Query: "show create table test;", + Expected: []sql.Row{ {"test", "CREATE TABLE `test` (\n" + - " `pk` bigint NOT NULL,\n" + - " `a` int,\n" + - " PRIMARY KEY (`pk`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, + " `pk` bigint NOT NULL,\n" + + " `a` int,\n" + + " PRIMARY KEY (`pk`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, }, }, { User: "tester", Host: "localhost", - Query: "alter table test add constraint chk1 CHECK (a < 10);", + Query: "alter table test add constraint chk1 CHECK (a < 10);", Expected: []sql.Row{}, }, { @@ -794,19 +794,19 @@ var DoltOnlyRevisionDbPrivilegeTests = []queries.UserPrivilegeTest{ { User: "tester", Host: "localhost", - Query: "alter table test drop constraint chk1;", + Query: "alter table test drop constraint chk1;", Expected: []sql.Row{}, }, { - User: "tester", - Host: "localhost", - Query: "show create table test;", - Expected: []sql.Row{ + User: "tester", + Host: "localhost", + Query: "show create table test;", + Expected: []sql.Row{ {"test", "CREATE TABLE `test` (\n" + - " `pk` bigint NOT NULL,\n" + - " `a` int,\n" + - " PRIMARY KEY (`pk`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, + " `pk` bigint NOT NULL,\n" + + " `a` int,\n" + + " PRIMARY KEY (`pk`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, }, }, }, @@ -1019,4 +1019,4 @@ func TestDoltOnlyRevisionDatabasePrivileges(t *testing.T) { } }) } -} \ No newline at end of file +} From 4bc0d266d5fe8df693c7d2adf1c732b5098e0fce Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 5 Jun 2023 11:04:02 -0700 Subject: [PATCH 141/167] Removed redundant call to setSessionVarsForDb --- go/libraries/doltcore/sqle/dsess/session.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 747904005c..901672fa96 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -951,7 +951,7 @@ func (d *DoltSession) SwitchWorkingSet( d.mu.Unlock() // bootstrap the db state as necessary - _, ok, err = d.lookupDbState(ctx, baseName+DbRevisionDelimiter+headRef.GetPath()) + branchState, ok, err := d.lookupDbState(ctx, baseName+DbRevisionDelimiter+headRef.GetPath()) if err != nil { return err } @@ -961,8 +961,8 @@ func (d *DoltSession) SwitchWorkingSet( } ctx.SetCurrentDatabase(baseName) - - return nil + + return d.setSessionVarsForDb(ctx, dbName, branchState) } func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { @@ -1209,13 +1209,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { branchState.headRoot = dbState.HeadRoot } - // This has to happen after SetWorkingSet above, since it does a stale check before its work branchState.headCommit = dbState.HeadCommit - - if sessionState.Err == nil { - return d.setSessionVarsForDb(ctx, db.Name(), branchState) - } - return nil } From 828ad1a631a276ac5d35a454984b31b52a212db1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 5 Jun 2023 14:47:46 -0700 Subject: [PATCH 142/167] restored session cache --- .../sqle/dsess/database_session_state.go | 29 ++++++++++++++----- go/libraries/doltcore/sqle/dsess/session.go | 3 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 566ab9009f..cdcf7c3108 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -72,6 +72,10 @@ type DatabaseSessionState struct { checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState + // caches records the session-caches for every branch head accessed by the session + // This is managed separately from the branch states themselves because it persists across transactions (which is + // safe because it's keyed by immutable hashes) + caches map[string]*SessionCache // globalState is the global state of this session (shared by all sessions for a particular db) globalState globalstate.GlobalState // tmpFileDir is the directory to use for temporary files for this database @@ -86,6 +90,7 @@ type DatabaseSessionState struct { func NewEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ heads: make(map[string]*branchState), + caches: make(map[string]*SessionCache), } } @@ -103,6 +108,8 @@ type SessionState interface { type branchState struct { // dbState is the parent database state for this branch head state dbState *DatabaseSessionState + // head is the name of the branch head for this state + head string // headCommit is the head commit for this database. May be nil for databases tied to a detached root value, in which // case headRoot must be set. headCommit *doltdb.Commit @@ -117,17 +124,25 @@ type branchState struct { writeSession writer.WriteSession // readOnly is true if this database is read only readOnly bool - // sessionCache is a collection of cached values used to speed up performance - sessionCache *SessionCache // dirty is true if this branch state has uncommitted changes dirty bool } -func NewEmptyBranchState(dbState *DatabaseSessionState) *branchState { - return &branchState{ - dbState: dbState, - sessionCache: newSessionCache(), +// NewEmptyBranchState creates a new branch state for the given head name with the head provided, adds it to the db +// state, and returns it. The state returned is empty except for its identifiers and must be filled in by the caller. +func (dbState *DatabaseSessionState) NewEmptyBranchState(head string) *branchState { + b := &branchState{ + dbState: dbState, + head: head, } + + dbState.heads[head] = b + _, ok := dbState.caches[head] + if !ok { + dbState.caches[head] = newSessionCache() + } + + return b } func (bs *branchState) WorkingRoot() *doltdb.RootValue { @@ -145,7 +160,7 @@ func (bs *branchState) WriteSession() writer.WriteSession { } func (bs *branchState) SessionCache() *SessionCache { - return bs.sessionCache + return bs.dbState.caches[bs.head] } func (bs branchState) EditOpts() editor.Options { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 901672fa96..39bc592cec 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1156,8 +1156,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { sessionState.currRevSpec = db.Revision() } - branchState := NewEmptyBranchState(sessionState) - sessionState.heads[strings.ToLower(db.Revision())] = branchState + branchState := sessionState.NewEmptyBranchState(strings.ToLower(db.Revision())) d.mu.Unlock() // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and From a13a4f0e0b0c54a574144cb41f7742e095ac42d1 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 5 Jun 2023 16:25:01 -0700 Subject: [PATCH 143/167] Added global caching for databases to avoid expensive lookups on names --- .../doltcore/sqle/database_provider.go | 5 +- .../sqle/dsess/database_session_state.go | 18 ++-- go/libraries/doltcore/sqle/dsess/session.go | 43 ++++++--- .../doltcore/sqle/dsess/session_cache.go | 93 ++++++++++++++++++- 4 files changed, 136 insertions(+), 23 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 6f872b00a5..66f0b4c93c 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1086,9 +1086,8 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds revisionQualifiedName := name usingDefaultBranch := false head := "" + sess := dsess.DSessFromSess(ctx.Session) if !isRevisionDbName { - sess := dsess.DSessFromSess(ctx.Session) - var err error head, ok, err = sess.CurrentHead(ctx, baseName) if err != nil { @@ -1108,7 +1107,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds revisionQualifiedName = baseName + dsess.DbRevisionDelimiter + head } - + db, ok, err := p.databaseForRevision(ctx, revisionQualifiedName, name) if err != nil { if sql.ErrDatabaseNotFound.Is(err) && usingDefaultBranch { diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index cdcf7c3108..4412d4353e 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -72,10 +72,13 @@ type DatabaseSessionState struct { checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState - // caches records the session-caches for every branch head accessed by the session + // globalCache records cache information for the entire session to speed up reads when nothing has changed since the + // last transaction + globalCache *SessionCache + // headCache records the session-caches for every branch head accessed by the session // This is managed separately from the branch states themselves because it persists across transactions (which is // safe because it's keyed by immutable hashes) - caches map[string]*SessionCache + headCache map[string]*SessionCache // globalState is the global state of this session (shared by all sessions for a particular db) globalState globalstate.GlobalState // tmpFileDir is the directory to use for temporary files for this database @@ -89,8 +92,9 @@ type DatabaseSessionState struct { func NewEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ - heads: make(map[string]*branchState), - caches: make(map[string]*SessionCache), + heads: make(map[string]*branchState), + headCache: make(map[string]*SessionCache), + globalCache: newSessionCache(), } } @@ -137,9 +141,9 @@ func (dbState *DatabaseSessionState) NewEmptyBranchState(head string) *branchSta } dbState.heads[head] = b - _, ok := dbState.caches[head] + _, ok := dbState.headCache[head] if !ok { - dbState.caches[head] = newSessionCache() + dbState.headCache[head] = newSessionCache() } return b @@ -160,7 +164,7 @@ func (bs *branchState) WriteSession() writer.WriteSession { } func (bs *branchState) SessionCache() *SessionCache { - return bs.dbState.caches[bs.head] + return bs.dbState.headCache[bs.head] } func (bs branchState) EditOpts() editor.Options { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 39bc592cec..6caedf1dbe 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -146,10 +146,10 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta baseName, rev = SplitRevisionDbName(dbName) d.mu.Lock() - dbState, ok := d.dbStates[baseName] + dbState, dbStateFound := d.dbStates[baseName] d.mu.Unlock() - if ok { + if dbStateFound { // If we got an unqualified name, use the current working set head if rev == "" { rev = dbState.currRevSpec @@ -174,24 +174,45 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta revisionQualifiedName = revisionDbName(baseName, rev) } - database, ok, err := d.provider.SessionDatabase(ctx, revisionQualifiedName) - if err != nil { - return nil, false, err + // Try to get the session from the cache before going to the provider + tx, usingDoltTransaction := d.GetTransaction().(*DoltTransaction) + var database SqlDatabase + if usingDoltTransaction && dbStateFound { + nomsRoot, ok := tx.GetInitialRoot(baseName) + if ok { + database, ok = dbState.globalCache.GetCachedRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) + } } - if !ok { - return nil, false, nil - } + if database == nil { + var err error + var ok bool + database, ok, err = d.provider.SessionDatabase(ctx, revisionQualifiedName) + if err != nil { + return nil, false, err + } + if !ok { + return nil, false, nil + } + if usingDoltTransaction { + nomsRoot, ok := tx.GetInitialRoot(baseName) + if ok { + dbState.globalCache.CacheRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, database) + } + } + } + // Add the initial state to the session for future reuse - if err = d.addDB(ctx, database); err != nil { + if err := d.addDB(ctx, database); err != nil { return nil, false, err } d.mu.Lock() - dbState, ok = d.dbStates[baseName] + dbState, dbStateFound = d.dbStates[baseName] d.mu.Unlock() - if !ok { + if !dbStateFound { + // should be impossible return nil, false, sql.ErrDatabaseNotFound.New(dbName) } diff --git a/go/libraries/doltcore/sqle/dsess/session_cache.go b/go/libraries/doltcore/sqle/dsess/session_cache.go index 37fc55b08b..a53c1ca023 100755 --- a/go/libraries/doltcore/sqle/dsess/session_cache.go +++ b/go/libraries/doltcore/sqle/dsess/session_cache.go @@ -24,12 +24,16 @@ import ( ) // SessionCache caches various pieces of expensive to compute information to speed up future lookups in the session. -// No methods are thread safe. type SessionCache struct { indexes map[doltdb.DataCacheKey]map[string][]sql.Index tables map[doltdb.DataCacheKey]map[string]sql.Table views map[doltdb.DataCacheKey]map[string]sql.ViewDefinition - + + // unlike the other caches, the database cache is keyed by noms root hash, not a rootValue hash. Keys in the + // secondary map are revision specifier strings + revisionDbs map[doltdb.DataCacheKey]map[string]SqlDatabase + initialDbStates map[doltdb.DataCacheKey]map[string]InitialDbState + mu sync.RWMutex } @@ -193,3 +197,88 @@ func (c *SessionCache) GetCachedViewDefinition(key doltdb.DataCacheKey, viewName table, ok := viewsForKey[viewName] return table, ok } + +// GetCachedRevisionDb returns the cached revision database named, and whether the cache was present +func (c *SessionCache) GetCachedRevisionDb(key doltdb.DataCacheKey, revisionDbName string) (SqlDatabase, bool) { + c.mu.RLock() + defer c.mu.RUnlock() + + if c.revisionDbs == nil { + return nil, false + } + + dbsForKey, ok := c.revisionDbs[key] + if !ok { + return nil, false + } + + db, ok := dbsForKey[revisionDbName] + return db, ok +} + +// CacheRevisionDb caches the revision database named +func (c *SessionCache) CacheRevisionDb(key doltdb.DataCacheKey, revisionDbName string, database SqlDatabase) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.revisionDbs == nil { + c.revisionDbs = make(map[doltdb.DataCacheKey]map[string]SqlDatabase) + } + + if len(c.revisionDbs) > maxCachedKeys { + for k := range c.revisionDbs { + delete(c.revisionDbs, k) + } + } + + dbsForKey, ok := c.revisionDbs[key] + if !ok { + dbsForKey = make(map[string]SqlDatabase) + c.revisionDbs[key] = dbsForKey + } + + dbsForKey[revisionDbName] = database +} + +// GetCachedInitialDbState returns the cached initial state for the revision database named, and whether the cache +// was present +func (c *SessionCache) GetCachedInitialDbState(key doltdb.DataCacheKey, revisionDbName string) (InitialDbState, bool) { + c.mu.RLock() + defer c.mu.RUnlock() + + if c.initialDbStates == nil { + return InitialDbState{}, false + } + + dbsForKey, ok := c.initialDbStates[key] + if !ok { + return InitialDbState{}, false + } + + db, ok := dbsForKey[revisionDbName] + return db, ok +} + +// CacheInitialDbState caches the initials state for the revision database named +func (c *SessionCache) CacheInitialDbState(key doltdb.DataCacheKey, revisionDbName string, state InitialDbState) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.initialDbStates == nil { + c.initialDbStates = make(map[doltdb.DataCacheKey]map[string]InitialDbState) + } + + if len(c.initialDbStates) > maxCachedKeys { + for k := range c.initialDbStates { + delete(c.initialDbStates, k) + } + } + + dbsForKey, ok := c.initialDbStates[key] + if !ok { + dbsForKey = make(map[string]InitialDbState) + c.initialDbStates[key] = dbsForKey + } + + dbsForKey[revisionDbName] = state +} \ No newline at end of file From 7243a36d2b69091ab4639a4ef7c3f0d4e57c9f23 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 5 Jun 2023 16:36:22 -0700 Subject: [PATCH 144/167] Removed useless param from SessionDatabase.InitialState() --- .../doltcore/sqle/clusterdb/database.go | 2 +- go/libraries/doltcore/sqle/database.go | 8 ++++---- .../sqle/dsess/database_session_state.go | 4 ++-- go/libraries/doltcore/sqle/dsess/session.go | 20 +++++++++---------- .../doltcore/sqle/read_replica_database.go | 4 ++-- .../doltcore/sqle/user_space_database.go | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/go/libraries/doltcore/sqle/clusterdb/database.go b/go/libraries/doltcore/sqle/clusterdb/database.go index 8469c30ea1..4005cb6921 100644 --- a/go/libraries/doltcore/sqle/clusterdb/database.go +++ b/go/libraries/doltcore/sqle/clusterdb/database.go @@ -100,7 +100,7 @@ func (database) IsReadOnly() bool { return true } -func (db database) InitialDBState(ctx *sql.Context, branch string) (dsess.InitialDbState, error) { +func (db database) InitialDBState(ctx *sql.Context) (dsess.InitialDbState, error) { // TODO: almost none of this state is actually used, but is necessary because the current session setup requires a // repo state writer return dsess.InitialDbState{ diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 924e8e7210..62769c396c 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -88,8 +88,8 @@ func (r ReadOnlyDatabase) IsReadOnly() bool { return true } -func (r ReadOnlyDatabase) InitialDBState(ctx *sql.Context, branch string) (dsess.InitialDbState, error) { - return initialDBState(ctx, r, branch) +func (r ReadOnlyDatabase) InitialDBState(ctx *sql.Context) (dsess.InitialDbState, error) { + return initialDBState(ctx, r, r.revision) } // Revision implements dsess.RevisionDatabase @@ -137,8 +137,8 @@ func initialDBState(ctx *sql.Context, db dsess.SqlDatabase, branch string) (dses return initialDbState(ctx, db, branch) } -func (db Database) InitialDBState(ctx *sql.Context, branch string) (dsess.InitialDbState, error) { - return initialDBState(ctx, db, branch) +func (db Database) InitialDBState(ctx *sql.Context) (dsess.InitialDbState, error) { + return initialDBState(ctx, db, db.revision) } // Name returns the name of this database, set at creation time. diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 4412d4353e..605e3148f5 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -53,7 +53,7 @@ type InitialDbState struct { // order for the session to manage it. type SessionDatabase interface { sql.Database - InitialDBState(ctx *sql.Context, branch string) (InitialDbState, error) + InitialDBState(ctx *sql.Context) (InitialDbState, error) } // DatabaseSessionState is the set of all information for a given database in this session. @@ -90,7 +90,7 @@ type DatabaseSessionState struct { Err error } -func NewEmptyDatabaseSessionState() *DatabaseSessionState { +func newEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ heads: make(map[string]*branchState), headCache: make(map[string]*SessionCache), diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 6caedf1dbe..8710fcb9e8 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -194,13 +194,6 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta if !ok { return nil, false, nil } - - if usingDoltTransaction { - nomsRoot, ok := tx.GetInitialRoot(baseName) - if ok { - dbState.globalCache.CacheRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, database) - } - } } // Add the initial state to the session for future reuse @@ -1136,8 +1129,8 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { DefineSystemVariablesForDB(baseName) - // TODO: odd that we need to tell the DB what its own revision is here - dbState, err := db.InitialDBState(ctx, db.Revision()) + tx, usingDoltTransaction := d.GetTransaction().(*DoltTransaction) + dbState, err := db.InitialDBState(ctx) if err != nil { return err } @@ -1145,7 +1138,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { d.mu.Lock() sessionState, ok := d.dbStates[strings.ToLower(baseName)] if !ok { - sessionState = NewEmptyDatabaseSessionState() + sessionState = newEmptyDatabaseSessionState() d.dbStates[strings.ToLower(baseName)] = sessionState sessionState.tmpFileDir, err = dbState.DbData.Rsw.TempTableFilesDir() @@ -1175,6 +1168,13 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { sessionState.currRevType = db.RevisionType() sessionState.currRevSpec = db.Revision() + + if usingDoltTransaction { + nomsRoot, ok := tx.GetInitialRoot(baseName) + if ok { + sessionState.globalCache.CacheRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, db) + } + } } branchState := sessionState.NewEmptyBranchState(strings.ToLower(db.Revision())) diff --git a/go/libraries/doltcore/sqle/read_replica_database.go b/go/libraries/doltcore/sqle/read_replica_database.go index 4e5672d45c..58592c4060 100644 --- a/go/libraries/doltcore/sqle/read_replica_database.go +++ b/go/libraries/doltcore/sqle/read_replica_database.go @@ -94,8 +94,8 @@ func (rrd ReadReplicaDatabase) ValidReplicaState(ctx *sql.Context) bool { // InitialDBState implements dsess.SessionDatabase // This seems like a pointless override from the embedded Database implementation, but it's necessary to pass the // correct pointer type to the session initializer. -func (rrd ReadReplicaDatabase) InitialDBState(ctx *sql.Context, branch string) (dsess.InitialDbState, error) { - return initialDBState(ctx, rrd, branch) +func (rrd ReadReplicaDatabase) InitialDBState(ctx *sql.Context) (dsess.InitialDbState, error) { + return initialDBState(ctx, rrd, rrd.revision) } func (rrd ReadReplicaDatabase) PullFromRemote(ctx *sql.Context) error { diff --git a/go/libraries/doltcore/sqle/user_space_database.go b/go/libraries/doltcore/sqle/user_space_database.go index 6c34dd2d50..721429a787 100644 --- a/go/libraries/doltcore/sqle/user_space_database.go +++ b/go/libraries/doltcore/sqle/user_space_database.go @@ -76,7 +76,7 @@ func (db *UserSpaceDatabase) GetTableNames(ctx *sql.Context) ([]string, error) { return resultingTblNames, nil } -func (db *UserSpaceDatabase) InitialDBState(ctx *sql.Context, branch string) (dsess.InitialDbState, error) { +func (db *UserSpaceDatabase) InitialDBState(ctx *sql.Context) (dsess.InitialDbState, error) { return dsess.InitialDbState{ Db: db, ReadOnly: true, From d7c2920a78beadcf03b88f33bf3bbc460a1aced9 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Mon, 5 Jun 2023 17:06:53 -0700 Subject: [PATCH 145/167] More caching --- go/libraries/doltcore/sqle/dsess/session.go | 46 ++++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 8710fcb9e8..abb9131e2c 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1124,23 +1124,40 @@ func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { // addDB adds the database given to this session. This establishes a starting root value for this session, as well as // other state tracking metadata. func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { - revisionQualifiedName := db.Name() - baseName, _ := SplitRevisionDbName(revisionQualifiedName) + revisionQualifiedName := strings.ToLower(db.RevisionQualifiedName()) + baseName, rev := SplitRevisionDbName(revisionQualifiedName) DefineSystemVariablesForDB(baseName) tx, usingDoltTransaction := d.GetTransaction().(*DoltTransaction) - dbState, err := db.InitialDBState(ctx) - if err != nil { - return err - } d.mu.Lock() - sessionState, ok := d.dbStates[strings.ToLower(baseName)] - if !ok { - sessionState = newEmptyDatabaseSessionState() - d.dbStates[strings.ToLower(baseName)] = sessionState + defer d.mu.Unlock() + sessionState, sessionStateExists := d.dbStates[baseName] + // Before computing initial state for the DB, check to see if we have it in the cache + var dbState InitialDbState + var dbStateCached bool + if usingDoltTransaction { + nomsRoot, ok := tx.GetInitialRoot(baseName) + if ok && sessionStateExists { + dbState, dbStateCached = sessionState.globalCache.GetCachedInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) + } + } + + if !dbStateCached { + var err error + dbState, err = db.InitialDBState(ctx) + if err != nil { + return err + } + } + + if !sessionStateExists { + sessionState = newEmptyDatabaseSessionState() + d.dbStates[baseName] = sessionState + + var err error sessionState.tmpFileDir, err = dbState.DbData.Rsw.TempTableFilesDir() if err != nil { d.mu.Unlock() @@ -1177,7 +1194,14 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } } - branchState := sessionState.NewEmptyBranchState(strings.ToLower(db.Revision())) + if !dbStateCached && usingDoltTransaction { + nomsRoot, ok := tx.GetInitialRoot(baseName) + if ok { + sessionState.globalCache.CacheInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, dbState) + } + } + + branchState := sessionState.NewEmptyBranchState(rev) d.mu.Unlock() // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and From 799ec4aadfe1620631d283af7b45f260306c4dbe Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 09:14:57 -0700 Subject: [PATCH 146/167] Bug fix for state caching --- go/libraries/doltcore/sqle/database_provider.go | 1 + go/libraries/doltcore/sqle/dsess/session.go | 14 ++------------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 66f0b4c93c..3253826d45 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -714,6 +714,7 @@ func (p DoltDatabaseProvider) invalidateDbStateInAllSessions(ctx *sql.Context, n } func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQualifiedName string, requestedName string) (dsess.SqlDatabase, bool, error) { + // TODO: use session cache to get database if !strings.Contains(revisionQualifiedName, dsess.DbRevisionDelimiter) { return nil, false, nil } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index abb9131e2c..b11cd13b4f 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -180,7 +180,7 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta if usingDoltTransaction && dbStateFound { nomsRoot, ok := tx.GetInitialRoot(baseName) if ok { - database, ok = dbState.globalCache.GetCachedRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) + database, _ = dbState.globalCache.GetCachedRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) } } @@ -1160,7 +1160,6 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { var err error sessionState.tmpFileDir, err = dbState.DbData.Rsw.TempTableFilesDir() if err != nil { - d.mu.Unlock() if errors.Is(err, env.ErrDoltRepositoryNotFound) { return env.ErrFailedToAccessDB.New(dbState.Db.Name()) } @@ -1171,7 +1170,6 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { baseDb, ok := d.provider.BaseDatabase(ctx, baseName) if !ok { - d.mu.Unlock() return fmt.Errorf("unable to find database %s, this is a bug", baseName) } @@ -1179,30 +1177,22 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { // string otherwise sessionState.checkedOutRevSpec, err = DefaultHead(baseName, baseDb) if err != nil { - d.mu.Unlock() return err } sessionState.currRevType = db.RevisionType() sessionState.currRevSpec = db.Revision() - - if usingDoltTransaction { - nomsRoot, ok := tx.GetInitialRoot(baseName) - if ok { - sessionState.globalCache.CacheRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, db) - } - } } if !dbStateCached && usingDoltTransaction { nomsRoot, ok := tx.GetInitialRoot(baseName) if ok { sessionState.globalCache.CacheInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, dbState) + sessionState.globalCache.CacheRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, db) } } branchState := sessionState.NewEmptyBranchState(rev) - d.mu.Unlock() // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and // the writer with one that errors out From f409eb2c69e86f04c0ee271646172860220e8650 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 10:04:24 -0700 Subject: [PATCH 147/167] More db caching by name. Much faster, some bugs still --- .../doltcore/sqle/database_provider.go | 11 ++++- .../sqle/dsess/database_session_state.go | 12 ++--- go/libraries/doltcore/sqle/dsess/session.go | 24 +++++---- .../doltcore/sqle/dsess/session_cache.go | 49 ++++++++++--------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 3253826d45..6686eb709e 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -714,7 +714,6 @@ func (p DoltDatabaseProvider) invalidateDbStateInAllSessions(ctx *sql.Context, n } func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQualifiedName string, requestedName string) (dsess.SqlDatabase, bool, error) { - // TODO: use session cache to get database if !strings.Contains(revisionQualifiedName, dsess.DbRevisionDelimiter) { return nil, false, nil } @@ -722,6 +721,16 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual parts := strings.SplitN(revisionQualifiedName, dsess.DbRevisionDelimiter, 2) baseName, rev := parts[0], parts[1] + // Look in the session cache for this DB before doing any IO to figure out what's being asked for + sess := dsess.DSessFromSess(ctx.Session) + dbCache, ok := sess.DatabaseCache(ctx, baseName) + if ok { + db, ok := dbCache.GetCachedRevisionDb(revisionQualifiedName) + if ok { + return db, true, nil + } + } + p.mu.RLock() srcDb, ok := p.databases[formatDbMapKeyName(baseName)] p.mu.RUnlock() diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 605e3148f5..5d0c461c91 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -72,9 +72,9 @@ type DatabaseSessionState struct { checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState - // globalCache records cache information for the entire session to speed up reads when nothing has changed since the - // last transaction - globalCache *SessionCache + // databaseCache records database name resolution for the session to speed up database resolution when nothing has + // changed since the last transaction + databaseCache *DatabaseCache // headCache records the session-caches for every branch head accessed by the session // This is managed separately from the branch states themselves because it persists across transactions (which is // safe because it's keyed by immutable hashes) @@ -92,9 +92,9 @@ type DatabaseSessionState struct { func newEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ - heads: make(map[string]*branchState), - headCache: make(map[string]*SessionCache), - globalCache: newSessionCache(), + heads: make(map[string]*branchState), + headCache: make(map[string]*SessionCache), + databaseCache: newDatabaseCache(), } } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index b11cd13b4f..ef5d821266 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -175,13 +175,9 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta } // Try to get the session from the cache before going to the provider - tx, usingDoltTransaction := d.GetTransaction().(*DoltTransaction) var database SqlDatabase - if usingDoltTransaction && dbStateFound { - nomsRoot, ok := tx.GetInitialRoot(baseName) - if ok { - database, _ = dbState.globalCache.GetCachedRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) - } + if dbStateFound { + database, _ = dbState.databaseCache.GetCachedRevisionDb(revisionQualifiedName) } if database == nil { @@ -1141,7 +1137,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if usingDoltTransaction { nomsRoot, ok := tx.GetInitialRoot(baseName) if ok && sessionStateExists { - dbState, dbStateCached = sessionState.globalCache.GetCachedInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) + dbState, dbStateCached = sessionState.databaseCache.GetCachedInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) } } @@ -1187,8 +1183,8 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if !dbStateCached && usingDoltTransaction { nomsRoot, ok := tx.GetInitialRoot(baseName) if ok { - sessionState.globalCache.CacheInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, dbState) - sessionState.globalCache.CacheRevisionDb(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, db) + sessionState.databaseCache.CacheInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, dbState) + sessionState.databaseCache.CacheRevisionDb(revisionQualifiedName, db) } } @@ -1247,6 +1243,16 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { return nil } +func (d *DoltSession) DatabaseCache(ctx *sql.Context, dbName string) (*DatabaseCache, bool) { + d.mu.Lock() + defer d.mu.Unlock() + dbState, ok := d.dbStates[dbName] + if !ok { + return nil, false + } + return dbState.databaseCache, true +} + func (d *DoltSession) AddTemporaryTable(ctx *sql.Context, db string, tbl sql.Table) { d.tempTables[strings.ToLower(db)] = append(d.tempTables[strings.ToLower(db)], tbl) } diff --git a/go/libraries/doltcore/sqle/dsess/session_cache.go b/go/libraries/doltcore/sqle/dsess/session_cache.go index a53c1ca023..a84f00225e 100755 --- a/go/libraries/doltcore/sqle/dsess/session_cache.go +++ b/go/libraries/doltcore/sqle/dsess/session_cache.go @@ -29,11 +29,19 @@ type SessionCache struct { tables map[doltdb.DataCacheKey]map[string]sql.Table views map[doltdb.DataCacheKey]map[string]sql.ViewDefinition - // unlike the other caches, the database cache is keyed by noms root hash, not a rootValue hash. Keys in the - // secondary map are revision specifier strings - revisionDbs map[doltdb.DataCacheKey]map[string]SqlDatabase + mu sync.RWMutex +} + +// DatabaseCache stores databases and their initial states, offloading the compute / IO involved in resolving a +// database name to a particular database. This is safe only because the database objects themselves don't have any +// handles to data or state, but always defer to the session. Keys in the secondary map are revision specifier strings +type DatabaseCache struct { + // revisionDbs caches databases by name. The name is always lower case and revision qualified + revisionDbs map[string]SqlDatabase + // initialDbStates caches the initial state of databases by name for a given noms root, which is the primary key. + // The secondary key is the lower-case revision-qualified database name. initialDbStates map[doltdb.DataCacheKey]map[string]InitialDbState - + mu sync.RWMutex } @@ -43,6 +51,10 @@ func newSessionCache() *SessionCache { return &SessionCache{} } +func newDatabaseCache() *DatabaseCache { + return &DatabaseCache{} +} + // CacheTableIndexes caches all indexes for the table with the name given func (c *SessionCache) CacheTableIndexes(key doltdb.DataCacheKey, table string, indexes []sql.Index) { c.mu.Lock() @@ -199,30 +211,25 @@ func (c *SessionCache) GetCachedViewDefinition(key doltdb.DataCacheKey, viewName } // GetCachedRevisionDb returns the cached revision database named, and whether the cache was present -func (c *SessionCache) GetCachedRevisionDb(key doltdb.DataCacheKey, revisionDbName string) (SqlDatabase, bool) { +func (c *DatabaseCache) GetCachedRevisionDb(revisionDbName string) (SqlDatabase, bool) { c.mu.RLock() defer c.mu.RUnlock() if c.revisionDbs == nil { return nil, false } - - dbsForKey, ok := c.revisionDbs[key] - if !ok { - return nil, false - } - - db, ok := dbsForKey[revisionDbName] + + db, ok := c.revisionDbs[revisionDbName] return db, ok } // CacheRevisionDb caches the revision database named -func (c *SessionCache) CacheRevisionDb(key doltdb.DataCacheKey, revisionDbName string, database SqlDatabase) { +func (c *DatabaseCache) CacheRevisionDb(revisionDbName string, database SqlDatabase) { c.mu.Lock() defer c.mu.Unlock() if c.revisionDbs == nil { - c.revisionDbs = make(map[doltdb.DataCacheKey]map[string]SqlDatabase) + c.revisionDbs = make(map[string]SqlDatabase) } if len(c.revisionDbs) > maxCachedKeys { @@ -230,19 +237,13 @@ func (c *SessionCache) CacheRevisionDb(key doltdb.DataCacheKey, revisionDbName s delete(c.revisionDbs, k) } } - - dbsForKey, ok := c.revisionDbs[key] - if !ok { - dbsForKey = make(map[string]SqlDatabase) - c.revisionDbs[key] = dbsForKey - } - - dbsForKey[revisionDbName] = database + + c.revisionDbs[revisionDbName] = database } // GetCachedInitialDbState returns the cached initial state for the revision database named, and whether the cache // was present -func (c *SessionCache) GetCachedInitialDbState(key doltdb.DataCacheKey, revisionDbName string) (InitialDbState, bool) { +func (c *DatabaseCache) GetCachedInitialDbState(key doltdb.DataCacheKey, revisionDbName string) (InitialDbState, bool) { c.mu.RLock() defer c.mu.RUnlock() @@ -260,7 +261,7 @@ func (c *SessionCache) GetCachedInitialDbState(key doltdb.DataCacheKey, revision } // CacheInitialDbState caches the initials state for the revision database named -func (c *SessionCache) CacheInitialDbState(key doltdb.DataCacheKey, revisionDbName string, state InitialDbState) { +func (c *DatabaseCache) CacheInitialDbState(key doltdb.DataCacheKey, revisionDbName string, state InitialDbState) { c.mu.Lock() defer c.mu.Unlock() From 0775c59e849e44c4a472e4bee35ffcc0a75fba30 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 10:09:54 -0700 Subject: [PATCH 148/167] Caching bug fix --- .../doltcore/sqle/database_provider.go | 4 +++- go/libraries/doltcore/sqle/dsess/session.go | 22 +++++-------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 6686eb709e..ade8a836d5 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -726,7 +726,9 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual dbCache, ok := sess.DatabaseCache(ctx, baseName) if ok { db, ok := dbCache.GetCachedRevisionDb(revisionQualifiedName) - if ok { + // The db cache is keyed by the revision qualified name, but the request name must also match for it to be a + // cache hit + if ok && db.RequestedName() == requestedName { return db, true, nil } } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index ef5d821266..21da5ef5a6 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -174,24 +174,14 @@ func (d *DoltSession) lookupDbState(ctx *sql.Context, dbName string) (*branchSta revisionQualifiedName = revisionDbName(baseName, rev) } - // Try to get the session from the cache before going to the provider - var database SqlDatabase - if dbStateFound { - database, _ = dbState.databaseCache.GetCachedRevisionDb(revisionQualifiedName) + database, ok, err := d.provider.SessionDatabase(ctx, revisionQualifiedName) + if err != nil { + return nil, false, err + } + if !ok { + return nil, false, nil } - if database == nil { - var err error - var ok bool - database, ok, err = d.provider.SessionDatabase(ctx, revisionQualifiedName) - if err != nil { - return nil, false, err - } - if !ok { - return nil, false, nil - } - } - // Add the initial state to the session for future reuse if err := d.addDB(ctx, database); err != nil { return nil, false, err From 36d20de701de76996d95e910ca9afe3e8b14ef41 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 11:14:13 -0700 Subject: [PATCH 149/167] Moved db cache to top level field on session --- .../doltcore/sqle/database_provider.go | 14 +++++------ .../sqle/dsess/database_session_state.go | 3 --- go/libraries/doltcore/sqle/dsess/session.go | 20 ++++++++-------- .../doltcore/sqle/dsess/session_cache.go | 23 ++++++++++++++----- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index ade8a836d5..fa17dd4979 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -723,14 +723,12 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual // Look in the session cache for this DB before doing any IO to figure out what's being asked for sess := dsess.DSessFromSess(ctx.Session) - dbCache, ok := sess.DatabaseCache(ctx, baseName) - if ok { - db, ok := dbCache.GetCachedRevisionDb(revisionQualifiedName) - // The db cache is keyed by the revision qualified name, but the request name must also match for it to be a - // cache hit - if ok && db.RequestedName() == requestedName { - return db, true, nil - } + dbCache := sess.DatabaseCache(ctx) + db, ok := dbCache.GetCachedRevisionDb(revisionQualifiedName) + // The db cache is keyed by the revision qualified name, but the request name must also match for it to be a + // cache hit + if ok && db.RequestedName() == requestedName { + return db, true, nil } p.mu.RLock() diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 5d0c461c91..0201108600 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -72,9 +72,6 @@ type DatabaseSessionState struct { checkedOutRevSpec string // heads records the in-memory DB state for every branch head accessed by the session heads map[string]*branchState - // databaseCache records database name resolution for the session to speed up database resolution when nothing has - // changed since the last transaction - databaseCache *DatabaseCache // headCache records the session-caches for every branch head accessed by the session // This is managed separately from the branch states themselves because it persists across transactions (which is // safe because it's keyed by immutable hashes) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 21da5ef5a6..75a3422b21 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -63,6 +63,7 @@ type DoltSession struct { username string email string dbStates map[string]*DatabaseSessionState + dbCache *DatabaseCache provider DoltDatabaseProvider tempTables map[string][]sql.Table globalsConf config.ReadWriteConfig @@ -86,6 +87,7 @@ func DefaultSession(pro DoltDatabaseProvider) *DoltSession { username: "", email: "", dbStates: make(map[string]*DatabaseSessionState), + dbCache: newDatabaseCache(), provider: pro, tempTables: make(map[string][]sql.Table), globalsConf: config.NewMapConfig(make(map[string]string)), @@ -110,6 +112,7 @@ func NewDoltSession( username: username, email: email, dbStates: make(map[string]*DatabaseSessionState), + dbCache: newDatabaseCache(), provider: pro, tempTables: make(map[string][]sql.Table), globalsConf: globals, @@ -1127,7 +1130,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if usingDoltTransaction { nomsRoot, ok := tx.GetInitialRoot(baseName) if ok && sessionStateExists { - dbState, dbStateCached = sessionState.databaseCache.GetCachedInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) + dbState, dbStateCached = d.dbCache.GetCachedInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) } } @@ -1173,11 +1176,12 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { if !dbStateCached && usingDoltTransaction { nomsRoot, ok := tx.GetInitialRoot(baseName) if ok { - sessionState.databaseCache.CacheInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, dbState) - sessionState.databaseCache.CacheRevisionDb(revisionQualifiedName, db) + d.dbCache.CacheInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName, dbState) } } + d.dbCache.CacheRevisionDb(db) + branchState := sessionState.NewEmptyBranchState(rev) // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and @@ -1233,14 +1237,8 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { return nil } -func (d *DoltSession) DatabaseCache(ctx *sql.Context, dbName string) (*DatabaseCache, bool) { - d.mu.Lock() - defer d.mu.Unlock() - dbState, ok := d.dbStates[dbName] - if !ok { - return nil, false - } - return dbState.databaseCache, true +func (d *DoltSession) DatabaseCache(ctx *sql.Context) *DatabaseCache { + return d.dbCache } func (d *DoltSession) AddTemporaryTable(ctx *sql.Context, db string, tbl sql.Table) { diff --git a/go/libraries/doltcore/sqle/dsess/session_cache.go b/go/libraries/doltcore/sqle/dsess/session_cache.go index a84f00225e..f4e0889110 100755 --- a/go/libraries/doltcore/sqle/dsess/session_cache.go +++ b/go/libraries/doltcore/sqle/dsess/session_cache.go @@ -37,7 +37,7 @@ type SessionCache struct { // handles to data or state, but always defer to the session. Keys in the secondary map are revision specifier strings type DatabaseCache struct { // revisionDbs caches databases by name. The name is always lower case and revision qualified - revisionDbs map[string]SqlDatabase + revisionDbs map[revisionDbCacheKey]SqlDatabase // initialDbStates caches the initial state of databases by name for a given noms root, which is the primary key. // The secondary key is the lower-case revision-qualified database name. initialDbStates map[doltdb.DataCacheKey]map[string]InitialDbState @@ -45,6 +45,11 @@ type DatabaseCache struct { mu sync.RWMutex } +type revisionDbCacheKey struct { + dbName string + requestedName string +} + const maxCachedKeys = 64 func newSessionCache() *SessionCache { @@ -211,7 +216,7 @@ func (c *SessionCache) GetCachedViewDefinition(key doltdb.DataCacheKey, viewName } // GetCachedRevisionDb returns the cached revision database named, and whether the cache was present -func (c *DatabaseCache) GetCachedRevisionDb(revisionDbName string) (SqlDatabase, bool) { +func (c *DatabaseCache) GetCachedRevisionDb(revisionDbName string, requestedName string) (SqlDatabase, bool) { c.mu.RLock() defer c.mu.RUnlock() @@ -219,17 +224,20 @@ func (c *DatabaseCache) GetCachedRevisionDb(revisionDbName string) (SqlDatabase, return nil, false } - db, ok := c.revisionDbs[revisionDbName] + db, ok := c.revisionDbs[revisionDbCacheKey{ + dbName: revisionDbName, + requestedName: requestedName, + }] return db, ok } // CacheRevisionDb caches the revision database named -func (c *DatabaseCache) CacheRevisionDb(revisionDbName string, database SqlDatabase) { +func (c *DatabaseCache) CacheRevisionDb(database SqlDatabase) { c.mu.Lock() defer c.mu.Unlock() if c.revisionDbs == nil { - c.revisionDbs = make(map[string]SqlDatabase) + c.revisionDbs = make(map[revisionDbCacheKey]SqlDatabase) } if len(c.revisionDbs) > maxCachedKeys { @@ -238,7 +246,10 @@ func (c *DatabaseCache) CacheRevisionDb(revisionDbName string, database SqlDatab } } - c.revisionDbs[revisionDbName] = database + c.revisionDbs[revisionDbCacheKey{ + dbName: strings.ToLower(database.RevisionQualifiedName()), + requestedName: database.RequestedName(), + }] = database } // GetCachedInitialDbState returns the cached initial state for the revision database named, and whether the cache From dad01497bbfbb7d89930f4be7abde44d301eb717 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 11:14:40 -0700 Subject: [PATCH 150/167] Typo --- go/libraries/doltcore/sqle/dsess/database_session_state.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 0201108600..678d9fb911 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -91,7 +91,6 @@ func newEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ heads: make(map[string]*branchState), headCache: make(map[string]*SessionCache), - databaseCache: newDatabaseCache(), } } From bf4f066278a384280077f278828f0d5d32fa04ce Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 11:15:43 -0700 Subject: [PATCH 151/167] Another error --- go/libraries/doltcore/sqle/database_provider.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index fa17dd4979..55b0331a63 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -724,10 +724,8 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual // Look in the session cache for this DB before doing any IO to figure out what's being asked for sess := dsess.DSessFromSess(ctx.Session) dbCache := sess.DatabaseCache(ctx) - db, ok := dbCache.GetCachedRevisionDb(revisionQualifiedName) - // The db cache is keyed by the revision qualified name, but the request name must also match for it to be a - // cache hit - if ok && db.RequestedName() == requestedName { + db, ok := dbCache.GetCachedRevisionDb(revisionQualifiedName, requestedName) + if ok { return db, true, nil } From e47d68b45250c2edf7c7ce6aed45029338b55ee7 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 12:24:25 -0700 Subject: [PATCH 152/167] Session var caching, small win --- .../doltcore/sqle/database_provider.go | 5 +++ go/libraries/doltcore/sqle/dsess/session.go | 36 +++++++++++++------ .../doltcore/sqle/dsess/session_cache.go | 35 +++++++++++++++++- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index 55b0331a63..ad44a87c4f 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -762,6 +762,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual return nil, false, err } + dbCache.CacheRevisionDb(db) return db, true, nil case dsess.RevisionTypeTag: // TODO: this should be an interface, not a struct @@ -780,6 +781,8 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual if err != nil { return nil, false, err } + + dbCache.CacheRevisionDb(db) return db, true, nil case dsess.RevisionTypeCommit: // TODO: this should be an interface, not a struct @@ -796,6 +799,8 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revisionQual if err != nil { return nil, false, err } + + dbCache.CacheRevisionDb(db) return db, true, nil case dsess.RevisionTypeNone: // Returning an error with the fully qualified db name here is our only opportunity to do so in some cases (such diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 75a3422b21..e65613f892 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -303,6 +303,8 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } + // TODO: this check is relatively expensive, we should cache this value when it changes instead of looking it + // up on each transaction start if _, v, ok := sql.SystemVariables.GetGlobal(ReadReplicaRemote); ok && v != "" { err := ddb.Rebase(ctx) if err != nil && !IgnoreReplicationErrors() { @@ -336,7 +338,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra continue } - _ = d.setSessionVarsForDb(ctx, db.Name(), bs) + _ = d.setDbSessionVars(ctx, bs, false) } return tx, nil @@ -895,7 +897,6 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo } // SetWorkingSet sets the working set for this session. -// Unlike setting the working root alone, this method always marks the session dirty. func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb.WorkingSet) error { if ws == nil { panic("attempted to set a nil working set for the session") @@ -910,7 +911,7 @@ func (d *DoltSession) SetWorkingSet(ctx *sql.Context, dbName string, ws *doltdb. } branchState.workingSet = ws - err = d.setSessionVarsForDb(ctx, dbName, branchState) + err = d.setDbSessionVars(ctx, branchState, true) if err != nil { return err } @@ -965,7 +966,7 @@ func (d *DoltSession) SwitchWorkingSet( ctx.SetCurrentDatabase(baseName) - return d.setSessionVarsForDb(ctx, dbName, branchState) + return d.setDbSessionVars(ctx, branchState, false) } func (d *DoltSession) UseDatabase(ctx *sql.Context, db sql.Database) error { @@ -1180,8 +1181,6 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { } } - d.dbCache.CacheRevisionDb(db) - branchState := sessionState.NewEmptyBranchState(rev) // TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and @@ -1321,10 +1320,16 @@ func (d *DoltSession) BatchMode() batchMode { return d.batchMode } -// setSessionVarsForDb updates the three session vars that track the value of the session root hashes -func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state *branchState) error { - baseName, _ := SplitRevisionDbName(dbName) - +// setDbSessionVars updates the three session vars that track the value of the session root hashes +func (d *DoltSession) setDbSessionVars(ctx *sql.Context, state *branchState, force bool) error { + // This check is important even when we are forcing an update, because it updates the idea of staleness + varsStale := d.dbSessionVarsStale(ctx, state) + if !varsStale && !force { + return nil + } + + baseName := state.dbState.dbName + // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here if state.WorkingSet() != nil { @@ -1377,6 +1382,17 @@ func (d *DoltSession) setSessionVarsForDb(ctx *sql.Context, dbName string, state return nil } +// dbSessionVarsStale returns whether the session vars for the database with the state provided need to be updated in +// the session +func (d *DoltSession) dbSessionVarsStale(ctx *sql.Context, state *branchState) bool { + dtx, ok := ctx.GetTransaction().(*DoltTransaction) + if !ok { + return true + } + + return d.dbCache.CacheSessionVars(state, dtx) +} + func (d DoltSession) WithGlobals(conf config.ReadWriteConfig) *DoltSession { d.globalsConf = conf return &d diff --git a/go/libraries/doltcore/sqle/dsess/session_cache.go b/go/libraries/doltcore/sqle/dsess/session_cache.go index f4e0889110..c42902c714 100755 --- a/go/libraries/doltcore/sqle/dsess/session_cache.go +++ b/go/libraries/doltcore/sqle/dsess/session_cache.go @@ -41,6 +41,8 @@ type DatabaseCache struct { // initialDbStates caches the initial state of databases by name for a given noms root, which is the primary key. // The secondary key is the lower-case revision-qualified database name. initialDbStates map[doltdb.DataCacheKey]map[string]InitialDbState + // sessionVars records a key for the most recently used session vars for each database in the session + sessionVars map[string]sessionVarCacheKey mu sync.RWMutex } @@ -50,6 +52,11 @@ type revisionDbCacheKey struct { requestedName string } +type sessionVarCacheKey struct { + root doltdb.DataCacheKey + head string +} + const maxCachedKeys = 64 func newSessionCache() *SessionCache { @@ -57,7 +64,9 @@ func newSessionCache() *SessionCache { } func newDatabaseCache() *DatabaseCache { - return &DatabaseCache{} + return &DatabaseCache{ + sessionVars: make(map[string]sessionVarCacheKey), + } } // CacheTableIndexes caches all indexes for the table with the name given @@ -293,4 +302,28 @@ func (c *DatabaseCache) CacheInitialDbState(key doltdb.DataCacheKey, revisionDbN } dbsForKey[revisionDbName] = state +} + +// CacheSessionVars updates the session var cache for the given branch state and transaction and returns whether it +// was updated. If it was updated, session vars need to be set for the state and transaction given. Otherwise they +// haven't changed and can be reused. +func (c *DatabaseCache) CacheSessionVars(branchState *branchState, transaction *DoltTransaction) bool { + c.mu.Lock() + defer c.mu.Unlock() + + dbBaseName := branchState.dbState.dbName + + existingKey, found := c.sessionVars[dbBaseName] + root, hasRoot := transaction.GetInitialRoot(dbBaseName) + if !hasRoot { + return true + } + + newKey := sessionVarCacheKey{ + root: doltdb.DataCacheKey{Hash: root}, + head: branchState.head, + } + + c.sessionVars[dbBaseName] = newKey + return !found || existingKey != newKey } \ No newline at end of file From 128d401e1b12f40b38e5f2b6d25f9e596b2ece01 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 12:34:25 -0700 Subject: [PATCH 153/167] Bug fix for session caching --- go/libraries/doltcore/sqle/enginetest/dolt_harness.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_harness.go b/go/libraries/doltcore/sqle/enginetest/dolt_harness.go index b429c70ce2..8296fd6d3c 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_harness.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_harness.go @@ -355,6 +355,10 @@ func (d *DoltHarness) NewReadOnlyEngine(provider sql.DatabaseProvider) (*gms.Eng if err != nil { return nil, err } + + // reset the session as well since we have swapped out the database provider, which invalidates caching assumptions + d.session, err = dsess.NewDoltSession(enginetest.NewBaseSession(), readOnlyProvider, d.multiRepoEnv.Config(), d.branchControl) + require.NoError(d.t, err) return enginetest.NewEngineWithProvider(nil, d, readOnlyProvider), nil } From 947771215b8e1eb3d0f8c97059437d4a265245f6 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 12:58:01 -0700 Subject: [PATCH 154/167] Deleted unused function --- go/libraries/doltcore/sqle/dsess/session.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index e65613f892..3fb34939db 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1103,14 +1103,6 @@ func (d *DoltSession) setForeignKeyChecksSessionVar(ctx *sql.Context, key string return d.Session.SetSessionVariable(ctx, key, value) } -// HasDB returns true if |sess| is tracking state for this database. -func (d *DoltSession) HasDB(_ *sql.Context, dbName string) bool { - d.mu.Lock() - defer d.mu.Unlock() - _, ok := d.dbStates[strings.ToLower(dbName)] - return ok -} - // addDB adds the database given to this session. This establishes a starting root value for this session, as well as // other state tracking metadata. func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { From 99ded16534f6066ab70dd53a99b5764834c2764a Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 13:44:52 -0700 Subject: [PATCH 155/167] Added a clear method for databaseCache --- go/libraries/doltcore/sqle/dsess/session.go | 2 ++ go/libraries/doltcore/sqle/dsess/session_cache.go | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 3fb34939db..4176ce999d 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -235,6 +235,8 @@ func (d *DoltSession) RemoveDbState(_ *sql.Context, dbName string) error { d.mu.Lock() defer d.mu.Unlock() delete(d.dbStates, strings.ToLower(dbName)) + // also clear out any db-level caches for this db + d.dbCache.Clear() return nil } diff --git a/go/libraries/doltcore/sqle/dsess/session_cache.go b/go/libraries/doltcore/sqle/dsess/session_cache.go index c42902c714..ee66422646 100755 --- a/go/libraries/doltcore/sqle/dsess/session_cache.go +++ b/go/libraries/doltcore/sqle/dsess/session_cache.go @@ -326,4 +326,12 @@ func (c *DatabaseCache) CacheSessionVars(branchState *branchState, transaction * c.sessionVars[dbBaseName] = newKey return !found || existingKey != newKey +} + +func (c *DatabaseCache) Clear() { + c.mu.Lock() + defer c.mu.Unlock() + c.sessionVars = make(map[string]sessionVarCacheKey) + c.revisionDbs = make(map[revisionDbCacheKey]SqlDatabase) + c.initialDbStates = make(map[doltdb.DataCacheKey]map[string]InitialDbState) } \ No newline at end of file From e93f7ca52f0d97b96b7f081b6cc49d80ddb0dd5e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 15:04:24 -0700 Subject: [PATCH 156/167] Fixed correctness issues with harness.NewEngine --- go/libraries/doltcore/sqle/dsess/session.go | 1 + .../sqle/enginetest/dolt_engine_test.go | 64 +++++++++++-------- .../doltcore/sqle/enginetest/dolt_harness.go | 12 +++- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 4176ce999d..0ef033a3ef 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -1282,6 +1282,7 @@ func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef, // CurrentHead returns the current head for the db named, which must be unqualifed. Used for bootstrap resolving the // correct session head when a database name from the client is unqualified. +// TODO: audit uses, see if basename can be removed func (d *DoltSession) CurrentHead(ctx *sql.Context, dbName string) (string, bool, error) { dbName = strings.ToLower(dbName) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index ee88e4cd61..0549137334 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -115,30 +115,37 @@ func TestSingleQuery(t *testing.T) { // Convenience test for debugging a single query. Unskip and set to the desired query. func TestSingleScript(t *testing.T) { - // t.Skip() + t.Skip() - var script = queries.ScriptTest{ - Name: "committing to another branch on another database with dolt_transaction_commit", - SetUpScript: []string{ - "create table t1 (a int)", - "call dolt_add('.')", - "call dolt_commit('-am', 'new table')", - "call dolt_branch('b1')", - "create database db1", - "use db1", - "create table t1 (a int)", - "call dolt_add('.')", - "call dolt_commit('-am', 'new table')", - "call dolt_branch('b1')", - "commit", - "use mydb/b1", - "set autocommit = 1", - "set dolt_transaction_commit = 1", + var scripts = []queries.ScriptTest{ + { + Name: "ALTER TABLE RENAME COLUMN", + SetUpScript: []string{ + "ALTER TABLE child ADD CONSTRAINT fk1 FOREIGN KEY (v1) REFERENCES parent(v1);", + "ALTER TABLE parent RENAME COLUMN v1 TO v1_new;", + "ALTER TABLE child RENAME COLUMN v1 TO v1_new;", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "SHOW CREATE TABLE child;", + Expected: []sql.Row{{"child", "CREATE TABLE `child` (\n `id` int NOT NULL,\n `v1_new` int,\n `v2` int,\n PRIMARY KEY (`id`),\n KEY `v1` (`v1_new`),\n CONSTRAINT `fk1` FOREIGN KEY (`v1_new`) REFERENCES `parent` (`v1_new`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}}, + }, + }, }, - Assertions: []queries.ScriptTestAssertion{ - { - Query: "insert into `db1/b1`.t1 values (1)", - ExpectedErrStr: "no changes to dolt_commit on database mydb", + { + Name: "ALTER TABLE MODIFY COLUMN type change not allowed", + SetUpScript: []string{ + "ALTER TABLE child ADD CONSTRAINT fk1 FOREIGN KEY (v1) REFERENCES parent(v1);", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "ALTER TABLE parent MODIFY v1 MEDIUMINT;", + ExpectedErr: sql.ErrForeignKeyTypeChange, + }, + { + Query: "ALTER TABLE child MODIFY v1 MEDIUMINT;", + ExpectedErr: sql.ErrForeignKeyTypeChange, + }, }, }, } @@ -147,11 +154,14 @@ func TestSingleScript(t *testing.T) { cleanup := installTestCommitClock(tcc) defer cleanup() - sql.RunWithNowFunc(tcc.Now, func() error { - harness := newDoltHarness(t) - enginetest.TestScript(t, harness, script) - return nil - }) + harness := newDoltHarness(t) + harness.Setup(setup.MydbData, setup.Parent_childData) + for _, script := range scripts { + sql.RunWithNowFunc(tcc.Now, func() error { + enginetest.TestScript(t, harness, script) + return nil + }) + } } // Convenience test for debugging a single query. Unskip and set to the desired query. diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_harness.go b/go/libraries/doltcore/sqle/enginetest/dolt_harness.go index 8296fd6d3c..18e67dbd88 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_harness.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_harness.go @@ -163,7 +163,8 @@ func commitScripts(dbs []string) []setup.SetupScript { // NewEngine creates a new *gms.Engine or calls reset and clear scripts on the existing // engine for reuse. func (d *DoltHarness) NewEngine(t *testing.T) (*gms.Engine, error) { - if d.engine == nil { + initializeEngine := d.engine == nil + if initializeEngine { d.branchControl = branch_control.CreateDefaultController() pro := d.newProvider() @@ -172,7 +173,7 @@ func (d *DoltHarness) NewEngine(t *testing.T) (*gms.Engine, error) { d.provider = doltProvider var err error - d.session, err = dsess.NewDoltSession(enginetest.NewBaseSession(), doltProvider, d.multiRepoEnv.Config(), d.branchControl) + d.session, err = dsess.NewDoltSession(enginetest.NewBaseSession(), d.provider, d.multiRepoEnv.Config(), d.branchControl) require.NoError(t, err) e, err := enginetest.NewEngine(t, d, d.provider, d.setupData) @@ -203,6 +204,13 @@ func (d *DoltHarness) NewEngine(t *testing.T) (*gms.Engine, error) { d.engine.Analyzer.Catalog.MySQLDb = mysql_db.CreateEmptyMySQLDb() d.engine.Analyzer.Catalog.MySQLDb.AddRootAccount() + // Get a fresh session if we are reusing the engine + if !initializeEngine { + var err error + d.session, err = dsess.NewDoltSession(enginetest.NewBaseSession(), d.provider, d.multiRepoEnv.Config(), d.branchControl) + require.NoError(t, err) + } + ctx := enginetest.NewContext(d) e, err := enginetest.RunSetupScripts(ctx, d.engine, d.resetScripts(), d.SupportsNativeIndexCreation()) From 78108eb5c16c6753eabbed05a56499e8169ce2c2 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 15:18:44 -0700 Subject: [PATCH 157/167] upgrade gms after merge --- go/go.mod | 4 ++-- go/go.sum | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go/go.mod b/go/go.mod index a8b1bceb0a..b9b88b893c 100755 --- a/go/go.mod +++ b/go/go.mod @@ -15,7 +15,7 @@ require ( github.com/dolthub/fslock v0.0.3 github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 - github.com/dolthub/vitess v0.0.0-20230605213213-cbc62ca5fb39 + github.com/dolthub/vitess v0.0.0-20230606164345-6cb0d80700b2 github.com/dustin/go-humanize v1.0.0 github.com/fatih/color v1.13.0 github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 @@ -59,7 +59,7 @@ require ( github.com/cespare/xxhash v1.1.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.15.1-0.20230606163443-3036c6d7fff7 + github.com/dolthub/go-mysql-server v0.15.1-0.20230606221209-a8f0e24fc48a github.com/dolthub/swiss v0.1.0 github.com/goccy/go-json v0.10.2 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 diff --git a/go/go.sum b/go/go.sum index 85aab3613b..c690989f45 100755 --- a/go/go.sum +++ b/go/go.sum @@ -170,6 +170,8 @@ github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e h1:kPsT4a47cw github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168= github.com/dolthub/go-mysql-server v0.15.1-0.20230606163443-3036c6d7fff7 h1:Tpl0xYr2MqfZhENtHr+H166D41nLRpL+XPchLhRHcwQ= github.com/dolthub/go-mysql-server v0.15.1-0.20230606163443-3036c6d7fff7/go.mod h1:E1STXoY8HvbrOWwFOhHpMfIjgcjboBhFtSpRxPgiBOw= +github.com/dolthub/go-mysql-server v0.15.1-0.20230606221209-a8f0e24fc48a h1:lE1ylBwSwC4up5VlExNNyNfXFnJci09RDdsh9lIXfxs= +github.com/dolthub/go-mysql-server v0.15.1-0.20230606221209-a8f0e24fc48a/go.mod h1:TP8QrAsULBEK7nP0BHRSfZ9l8oiAeaRzIREHVk2wnz0= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto= github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72 h1:NfWmngMi1CYUWU4Ix8wM+USEhjc+mhPlT9JUR/anvbQ= @@ -182,6 +184,8 @@ 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-20230605213213-cbc62ca5fb39 h1:T1oXYVAZrpANwuyStC/SZGw4cYmPFMwq6n6KvK4U6Mw= github.com/dolthub/vitess v0.0.0-20230605213213-cbc62ca5fb39/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= +github.com/dolthub/vitess v0.0.0-20230606164345-6cb0d80700b2 h1:KGlVqYOuu6iG6DJAK06mZQPeXB/ElYlOH5UsuqUNf0A= +github.com/dolthub/vitess v0.0.0-20230606164345-6cb0d80700b2/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= From 27db95c567ddd90f69e5215f28b21a13dd7d219c Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 16:00:55 -0700 Subject: [PATCH 158/167] Fixed breaking change from gms main --- .../doltcore/sqle/enginetest/dolt_engine_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index f5ce1475b9..6a6768a1a8 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -28,6 +28,7 @@ import ( "github.com/dolthub/go-mysql-server/server" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/analyzer" + "github.com/dolthub/go-mysql-server/sql/memo" "github.com/dolthub/go-mysql-server/sql/mysql_db" gmstypes "github.com/dolthub/go-mysql-server/sql/types" "github.com/dolthub/vitess/go/mysql" @@ -2092,11 +2093,11 @@ func mustNewEngine(t *testing.T, h enginetest.Harness) *gms.Engine { return e } -var biasedCosters = []analyzer.Coster{ - analyzer.NewInnerBiasedCoster(), - analyzer.NewLookupBiasedCoster(), - analyzer.NewHashBiasedCoster(), - analyzer.NewMergeBiasedCoster(), +var biasedCosters = []memo.Coster{ + memo.NewInnerBiasedCoster(), + memo.NewLookupBiasedCoster(), + memo.NewHashBiasedCoster(), + memo.NewMergeBiasedCoster(), } func TestSystemTableIndexes(t *testing.T) { @@ -2110,7 +2111,7 @@ func TestSystemTableIndexes(t *testing.T) { harness.SkipSetupCommit() e := mustNewEngine(t, harness) defer e.Close() - e.Analyzer.Coster = analyzer.NewMergeBiasedCoster() + e.Analyzer.Coster = memo.NewMergeBiasedCoster() ctx := enginetest.NewContext(harness) for _, q := range stt.setup { From 836f3397c25350746117e810a3434640bdb22843 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 16:10:21 -0700 Subject: [PATCH 159/167] PR feedback and cleanup --- go/libraries/doltcore/sqle/database.go | 4 +- go/libraries/doltcore/sqle/dsess/session.go | 7 +- .../sqle/enginetest/dolt_engine_test.go | 1 - .../doltcore/sqle/enginetest/dolt_queries.go | 351 +++++++++--------- 4 files changed, 180 insertions(+), 183 deletions(-) diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 62769c396c..3ef7e44392 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -858,7 +858,7 @@ func (db Database) CreateIndexedTable(ctx *sql.Context, tableName string, sch sq return db.createIndexedSqlTable(ctx, tableName, sch, idxDef, collation) } -// Unlike the exported version CreateTable, createSqlTable doesn't enforce any table baseName checks. +// createSqlTable is the private version of CreateTable. It doesn't enforce any table name checks. func (db Database) createSqlTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, collation sql.CollationID) error { ws, err := db.GetWorkingSet(ctx) if err != nil { @@ -900,7 +900,7 @@ func (db Database) createSqlTable(ctx *sql.Context, tableName string, sch sql.Pr return db.createDoltTable(ctx, tableName, root, doltSch) } -// Unlike the exported version CreateTable, createSqlTable doesn't enforce any table baseName checks. +// createIndexedSqlTable is the private version of createSqlTable. It doesn't enforce any table name checks. func (db Database) createIndexedSqlTable(ctx *sql.Context, tableName string, sch sql.PrimaryKeySchema, idxDef sql.IndexDef, collation sql.CollationID) error { ws, err := db.GetWorkingSet(ctx) if err != nil { diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 0ef033a3ef..e558f87949 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -270,10 +270,7 @@ func (d *DoltSession) SetValidateErr(err error) { // If there is no sessionState or its current working set not defined, then no need for validation, // so no error is returned. func (d *DoltSession) ValidateSession(ctx *sql.Context, dbName string) error { - if d.validateErr != nil { - return d.validateErr - } - return nil + return d.validateErr } // StartTransaction refreshes the state of this session and starts a new transaction. @@ -327,7 +324,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra // The engine sets the transaction after this call as well, but since we begin accessing data below, we need to set // this now to avoid seeding the session state with stale data in some cases. The duplication is harmless since the - // code below cannot error, but it would to get rid of + // code below cannot error. ctx.SetTransaction(tx) // Set session vars for every DB in this session using their current branch head diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 6a6768a1a8..6014d6a12d 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -27,7 +27,6 @@ import ( "github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup" "github.com/dolthub/go-mysql-server/server" "github.com/dolthub/go-mysql-server/sql" - "github.com/dolthub/go-mysql-server/sql/analyzer" "github.com/dolthub/go-mysql-server/sql/memo" "github.com/dolthub/go-mysql-server/sql/mysql_db" gmstypes "github.com/dolthub/go-mysql-server/sql/types" diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index f6eb7bfd06..1f01c7a655 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -18,6 +18,7 @@ import ( "fmt" "strings" + "github.com/dolthub/dolt/go/libraries/doltcore/sqle" "github.com/dolthub/go-mysql-server/enginetest/queries" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/expression" @@ -2490,181 +2491,181 @@ var DoltGC = []queries.ScriptTest{ } var LogTableFunctionScriptTests = []queries.ScriptTest{ - // { - // Name: "invalid arguments", - // SetUpScript: []string{ - // "create table t (pk int primary key, c1 varchar(20), c2 varchar(20));", - // "call dolt_add('.')", - // "set @Commit1 = '';", - // "call dolt_commit_hash_out(@Commit1, '-am', 'creating table t');", - // - // "insert into t values(1, 'one', 'two'), (2, 'two', 'three');", - // "set @Commit2 = '';", - // "call dolt_commit_hash_out(@Commit2, '-am', 'inserting into t');", - // }, - // Assertions: []queries.ScriptTestAssertion{ - // { - // Query: "SELECT * from dolt_log(@Commit1, @Commit2, 't');", - // ExpectedErr: sql.ErrInvalidArgumentNumber, - // }, - // { - // Query: "SELECT * from dolt_log(null);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(null, null);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(null, '--not', null);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, '--not', null);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, '--min-parents', null);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, '--min-parents', 123);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(123, @Commit1);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, 123);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, '--not', 123);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('main..branch1', @Commit1);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('^main..branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('^main...branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, 'main..branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, 'main...branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('main..branch1', '--not', @Commit1);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('main...branch1', '--not', @Commit1);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('^main', '--not', @Commit1);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('main', '--not', '^branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('main', '--not', 'main..branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('^main', @Commit2, '--not', @Commit1);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, @Commit2);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('^main', '^branch1');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('^main');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('fake-branch');", - // ExpectedErrStr: "branch not found: fake-branch", - // }, - // { - // Query: "SELECT * from dolt_log('^fake-branch', 'main');", - // ExpectedErrStr: "branch not found: fake-branch", - // }, - // { - // Query: "SELECT * from dolt_log('fake-branch', '^main');", - // ExpectedErrStr: "branch not found: fake-branch", - // }, - // { - // Query: "SELECT * from dolt_log('main..fake-branch');", - // ExpectedErrStr: "branch not found: fake-branch", - // }, - // { - // Query: "SELECT * from dolt_log('main', '--not', 'fake-branch');", - // ExpectedErrStr: "branch not found: fake-branch", - // }, - // { - // Query: "SELECT * from dolt_log(concat('fake', '-', 'branch'));", - // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - // }, - // { - // Query: "SELECT * from dolt_log(hashof('main'));", - // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit3, '--not', hashof('main'));", - // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - // }, - // { - // Query: "SELECT * from dolt_log(@Commit1, LOWER(@Commit2));", - // ExpectedErr: sqle.ErrInvalidNonLiteralArgument, - // }, - // { - // Query: "SELECT parents from dolt_log();", - // ExpectedErrStr: `column "parents" could not be found in any table in scope`, - // }, - // { - // Query: "SELECT * from dolt_log('--decorate', 'invalid');", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('--decorate', 123);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT * from dolt_log('--decorate', null);", - // ExpectedErr: sql.ErrInvalidArgumentDetails, - // }, - // { - // Query: "SELECT refs from dolt_log();", - // ExpectedErrStr: `column "refs" could not be found in any table in scope`, - // }, - // { - // Query: "SELECT refs from dolt_log('--decorate', 'auto');", - // ExpectedErrStr: `column "refs" could not be found in any table in scope`, - // }, - // { - // Query: "SELECT refs from dolt_log('--decorate', 'no');", - // ExpectedErrStr: `column "refs" could not be found in any table in scope`, - // }, - // }, - // }, + { + Name: "invalid arguments", + SetUpScript: []string{ + "create table t (pk int primary key, c1 varchar(20), c2 varchar(20));", + "call dolt_add('.')", + "set @Commit1 = '';", + "call dolt_commit_hash_out(@Commit1, '-am', 'creating table t');", + + "insert into t values(1, 'one', 'two'), (2, 'two', 'three');", + "set @Commit2 = '';", + "call dolt_commit_hash_out(@Commit2, '-am', 'inserting into t');", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "SELECT * from dolt_log(@Commit1, @Commit2, 't');", + ExpectedErr: sql.ErrInvalidArgumentNumber, + }, + { + Query: "SELECT * from dolt_log(null);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(null, null);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(null, '--not', null);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, '--not', null);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, '--min-parents', null);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, '--min-parents', 123);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(123, @Commit1);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, 123);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, '--not', 123);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('main..branch1', @Commit1);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('^main..branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('^main...branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, 'main..branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, 'main...branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('main..branch1', '--not', @Commit1);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('main...branch1', '--not', @Commit1);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('^main', '--not', @Commit1);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('main', '--not', '^branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('main', '--not', 'main..branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('^main', @Commit2, '--not', @Commit1);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log(@Commit1, @Commit2);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('^main', '^branch1');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('^main');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('fake-branch');", + ExpectedErrStr: "branch not found: fake-branch", + }, + { + Query: "SELECT * from dolt_log('^fake-branch', 'main');", + ExpectedErrStr: "branch not found: fake-branch", + }, + { + Query: "SELECT * from dolt_log('fake-branch', '^main');", + ExpectedErrStr: "branch not found: fake-branch", + }, + { + Query: "SELECT * from dolt_log('main..fake-branch');", + ExpectedErrStr: "branch not found: fake-branch", + }, + { + Query: "SELECT * from dolt_log('main', '--not', 'fake-branch');", + ExpectedErrStr: "branch not found: fake-branch", + }, + { + Query: "SELECT * from dolt_log(concat('fake', '-', 'branch'));", + ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + }, + { + Query: "SELECT * from dolt_log(hashof('main'));", + ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + }, + { + Query: "SELECT * from dolt_log(@Commit3, '--not', hashof('main'));", + ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + }, + { + Query: "SELECT * from dolt_log(@Commit1, LOWER(@Commit2));", + ExpectedErr: sqle.ErrInvalidNonLiteralArgument, + }, + { + Query: "SELECT parents from dolt_log();", + ExpectedErrStr: `column "parents" could not be found in any table in scope`, + }, + { + Query: "SELECT * from dolt_log('--decorate', 'invalid');", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('--decorate', 123);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT * from dolt_log('--decorate', null);", + ExpectedErr: sql.ErrInvalidArgumentDetails, + }, + { + Query: "SELECT refs from dolt_log();", + ExpectedErrStr: `column "refs" could not be found in any table in scope`, + }, + { + Query: "SELECT refs from dolt_log('--decorate', 'auto');", + ExpectedErrStr: `column "refs" could not be found in any table in scope`, + }, + { + Query: "SELECT refs from dolt_log('--decorate', 'no');", + ExpectedErrStr: `column "refs" could not be found in any table in scope`, + }, + }, + }, { Name: "basic case with one revision", SetUpScript: []string{ From 5bfad729fe1bd8a170252853e3918dde6fcc595b Mon Sep 17 00:00:00 2001 From: zachmu Date: Tue, 6 Jun 2023 23:20:26 +0000 Subject: [PATCH 160/167] [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh --- go/go.sum | 4 --- .../doltcore/sqle/database_provider.go | 2 +- .../sqle/dsess/database_session_state.go | 8 ++--- go/libraries/doltcore/sqle/dsess/session.go | 20 +++++------ .../doltcore/sqle/dsess/session_cache.go | 34 +++++++++---------- .../doltcore/sqle/enginetest/dolt_harness.go | 2 +- .../doltcore/sqle/enginetest/dolt_queries.go | 5 +-- 7 files changed, 36 insertions(+), 39 deletions(-) diff --git a/go/go.sum b/go/go.sum index c690989f45..6bbd819e88 100755 --- a/go/go.sum +++ b/go/go.sum @@ -168,8 +168,6 @@ 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-20230524105445-af7e7991c97e h1:kPsT4a47cw1+y/N5SSCkma7FhAPw7KeGmD6c9PBZW9Y= github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168= -github.com/dolthub/go-mysql-server v0.15.1-0.20230606163443-3036c6d7fff7 h1:Tpl0xYr2MqfZhENtHr+H166D41nLRpL+XPchLhRHcwQ= -github.com/dolthub/go-mysql-server v0.15.1-0.20230606163443-3036c6d7fff7/go.mod h1:E1STXoY8HvbrOWwFOhHpMfIjgcjboBhFtSpRxPgiBOw= github.com/dolthub/go-mysql-server v0.15.1-0.20230606221209-a8f0e24fc48a h1:lE1ylBwSwC4up5VlExNNyNfXFnJci09RDdsh9lIXfxs= github.com/dolthub/go-mysql-server v0.15.1-0.20230606221209-a8f0e24fc48a/go.mod h1:TP8QrAsULBEK7nP0BHRSfZ9l8oiAeaRzIREHVk2wnz0= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= @@ -182,8 +180,6 @@ 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-20230605213213-cbc62ca5fb39 h1:T1oXYVAZrpANwuyStC/SZGw4cYmPFMwq6n6KvK4U6Mw= -github.com/dolthub/vitess v0.0.0-20230605213213-cbc62ca5fb39/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= github.com/dolthub/vitess v0.0.0-20230606164345-6cb0d80700b2 h1:KGlVqYOuu6iG6DJAK06mZQPeXB/ElYlOH5UsuqUNf0A= github.com/dolthub/vitess v0.0.0-20230606164345-6cb0d80700b2/go.mod h1:IyoysiiOzrIs7QsEHC+yVF0yRQ6W70GXyCXqtI2vVTs= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= diff --git a/go/libraries/doltcore/sqle/database_provider.go b/go/libraries/doltcore/sqle/database_provider.go index ad44a87c4f..30bd0dc30c 100644 --- a/go/libraries/doltcore/sqle/database_provider.go +++ b/go/libraries/doltcore/sqle/database_provider.go @@ -1120,7 +1120,7 @@ func (p DoltDatabaseProvider) SessionDatabase(ctx *sql.Context, name string) (ds revisionQualifiedName = baseName + dsess.DbRevisionDelimiter + head } - + db, ok, err := p.databaseForRevision(ctx, revisionQualifiedName, name) if err != nil { if sql.ErrDatabaseNotFound.Is(err) && usingDefaultBranch { diff --git a/go/libraries/doltcore/sqle/dsess/database_session_state.go b/go/libraries/doltcore/sqle/dsess/database_session_state.go index 678d9fb911..8259cb1e3c 100644 --- a/go/libraries/doltcore/sqle/dsess/database_session_state.go +++ b/go/libraries/doltcore/sqle/dsess/database_session_state.go @@ -89,8 +89,8 @@ type DatabaseSessionState struct { func newEmptyDatabaseSessionState() *DatabaseSessionState { return &DatabaseSessionState{ - heads: make(map[string]*branchState), - headCache: make(map[string]*SessionCache), + heads: make(map[string]*branchState), + headCache: make(map[string]*SessionCache), } } @@ -128,12 +128,12 @@ type branchState struct { dirty bool } -// NewEmptyBranchState creates a new branch state for the given head name with the head provided, adds it to the db +// NewEmptyBranchState creates a new branch state for the given head name with the head provided, adds it to the db // state, and returns it. The state returned is empty except for its identifiers and must be filled in by the caller. func (dbState *DatabaseSessionState) NewEmptyBranchState(head string) *branchState { b := &branchState{ dbState: dbState, - head: head, + head: head, } dbState.heads[head] = b diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index e558f87949..c3d7c7feb2 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -87,7 +87,7 @@ func DefaultSession(pro DoltDatabaseProvider) *DoltSession { username: "", email: "", dbStates: make(map[string]*DatabaseSessionState), - dbCache: newDatabaseCache(), + dbCache: newDatabaseCache(), provider: pro, tempTables: make(map[string][]sql.Table), globalsConf: config.NewMapConfig(make(map[string]string)), @@ -112,7 +112,7 @@ func NewDoltSession( username: username, email: email, dbStates: make(map[string]*DatabaseSessionState), - dbCache: newDatabaseCache(), + dbCache: newDatabaseCache(), provider: pro, tempTables: make(map[string][]sql.Table), globalsConf: globals, @@ -302,7 +302,7 @@ func (d *DoltSession) StartTransaction(ctx *sql.Context, tCharacteristic sql.Tra } } - // TODO: this check is relatively expensive, we should cache this value when it changes instead of looking it + // TODO: this check is relatively expensive, we should cache this value when it changes instead of looking it // up on each transaction start if _, v, ok := sql.SystemVariables.GetGlobal(ReadReplicaRemote); ok && v != "" { err := ddb.Rebase(ctx) @@ -964,7 +964,7 @@ func (d *DoltSession) SwitchWorkingSet( } ctx.SetCurrentDatabase(baseName) - + return d.setDbSessionVars(ctx, branchState, false) } @@ -1117,7 +1117,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { sessionState, sessionStateExists := d.dbStates[baseName] // Before computing initial state for the DB, check to see if we have it in the cache - var dbState InitialDbState + var dbState InitialDbState var dbStateCached bool if usingDoltTransaction { nomsRoot, ok := tx.GetInitialRoot(baseName) @@ -1125,7 +1125,7 @@ func (d *DoltSession) addDB(ctx *sql.Context, db SqlDatabase) error { dbState, dbStateCached = d.dbCache.GetCachedInitialDbState(doltdb.DataCacheKey{Hash: nomsRoot}, revisionQualifiedName) } } - + if !dbStateCached { var err error dbState, err = db.InitialDBState(ctx) @@ -1314,14 +1314,14 @@ func (d *DoltSession) BatchMode() batchMode { // setDbSessionVars updates the three session vars that track the value of the session root hashes func (d *DoltSession) setDbSessionVars(ctx *sql.Context, state *branchState, force bool) error { - // This check is important even when we are forcing an update, because it updates the idea of staleness + // This check is important even when we are forcing an update, because it updates the idea of staleness varsStale := d.dbSessionVarsStale(ctx, state) if !varsStale && !force { return nil } - + baseName := state.dbState.dbName - + // Different DBs have different requirements for what state is set, so we are maximally permissive on what's expected // in the state object here if state.WorkingSet() != nil { @@ -1381,7 +1381,7 @@ func (d *DoltSession) dbSessionVarsStale(ctx *sql.Context, state *branchState) b if !ok { return true } - + return d.dbCache.CacheSessionVars(state, dtx) } diff --git a/go/libraries/doltcore/sqle/dsess/session_cache.go b/go/libraries/doltcore/sqle/dsess/session_cache.go index ee66422646..7bd320ea56 100755 --- a/go/libraries/doltcore/sqle/dsess/session_cache.go +++ b/go/libraries/doltcore/sqle/dsess/session_cache.go @@ -28,12 +28,12 @@ type SessionCache struct { indexes map[doltdb.DataCacheKey]map[string][]sql.Index tables map[doltdb.DataCacheKey]map[string]sql.Table views map[doltdb.DataCacheKey]map[string]sql.ViewDefinition - + mu sync.RWMutex } -// DatabaseCache stores databases and their initial states, offloading the compute / IO involved in resolving a -// database name to a particular database. This is safe only because the database objects themselves don't have any +// DatabaseCache stores databases and their initial states, offloading the compute / IO involved in resolving a +// database name to a particular database. This is safe only because the database objects themselves don't have any // handles to data or state, but always defer to the session. Keys in the secondary map are revision specifier strings type DatabaseCache struct { // revisionDbs caches databases by name. The name is always lower case and revision qualified @@ -41,14 +41,14 @@ type DatabaseCache struct { // initialDbStates caches the initial state of databases by name for a given noms root, which is the primary key. // The secondary key is the lower-case revision-qualified database name. initialDbStates map[doltdb.DataCacheKey]map[string]InitialDbState - // sessionVars records a key for the most recently used session vars for each database in the session + // sessionVars records a key for the most recently used session vars for each database in the session sessionVars map[string]sessionVarCacheKey mu sync.RWMutex } type revisionDbCacheKey struct { - dbName string + dbName string requestedName string } @@ -228,11 +228,11 @@ func (c *SessionCache) GetCachedViewDefinition(key doltdb.DataCacheKey, viewName func (c *DatabaseCache) GetCachedRevisionDb(revisionDbName string, requestedName string) (SqlDatabase, bool) { c.mu.RLock() defer c.mu.RUnlock() - + if c.revisionDbs == nil { return nil, false } - + db, ok := c.revisionDbs[revisionDbCacheKey{ dbName: revisionDbName, requestedName: requestedName, @@ -248,20 +248,20 @@ func (c *DatabaseCache) CacheRevisionDb(database SqlDatabase) { if c.revisionDbs == nil { c.revisionDbs = make(map[revisionDbCacheKey]SqlDatabase) } - + if len(c.revisionDbs) > maxCachedKeys { for k := range c.revisionDbs { delete(c.revisionDbs, k) } } - + c.revisionDbs[revisionDbCacheKey{ - dbName: strings.ToLower(database.RevisionQualifiedName()), + dbName: strings.ToLower(database.RevisionQualifiedName()), requestedName: database.RequestedName(), }] = database } -// GetCachedInitialDbState returns the cached initial state for the revision database named, and whether the cache +// GetCachedInitialDbState returns the cached initial state for the revision database named, and whether the cache // was present func (c *DatabaseCache) GetCachedInitialDbState(key doltdb.DataCacheKey, revisionDbName string) (InitialDbState, bool) { c.mu.RLock() @@ -304,26 +304,26 @@ func (c *DatabaseCache) CacheInitialDbState(key doltdb.DataCacheKey, revisionDbN dbsForKey[revisionDbName] = state } -// CacheSessionVars updates the session var cache for the given branch state and transaction and returns whether it -// was updated. If it was updated, session vars need to be set for the state and transaction given. Otherwise they +// CacheSessionVars updates the session var cache for the given branch state and transaction and returns whether it +// was updated. If it was updated, session vars need to be set for the state and transaction given. Otherwise they // haven't changed and can be reused. func (c *DatabaseCache) CacheSessionVars(branchState *branchState, transaction *DoltTransaction) bool { c.mu.Lock() defer c.mu.Unlock() dbBaseName := branchState.dbState.dbName - + existingKey, found := c.sessionVars[dbBaseName] root, hasRoot := transaction.GetInitialRoot(dbBaseName) if !hasRoot { return true } - + newKey := sessionVarCacheKey{ root: doltdb.DataCacheKey{Hash: root}, head: branchState.head, } - + c.sessionVars[dbBaseName] = newKey return !found || existingKey != newKey } @@ -334,4 +334,4 @@ func (c *DatabaseCache) Clear() { c.sessionVars = make(map[string]sessionVarCacheKey) c.revisionDbs = make(map[revisionDbCacheKey]SqlDatabase) c.initialDbStates = make(map[doltdb.DataCacheKey]map[string]InitialDbState) -} \ No newline at end of file +} diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_harness.go b/go/libraries/doltcore/sqle/enginetest/dolt_harness.go index 18e67dbd88..1499852ba1 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_harness.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_harness.go @@ -363,7 +363,7 @@ func (d *DoltHarness) NewReadOnlyEngine(provider sql.DatabaseProvider) (*gms.Eng if err != nil { return nil, err } - + // reset the session as well since we have swapped out the database provider, which invalidates caching assumptions d.session, err = dsess.NewDoltSession(enginetest.NewBaseSession(), readOnlyProvider, d.multiRepoEnv.Config(), d.branchControl) require.NoError(d.t, err) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 1f01c7a655..81b59e9492 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -18,12 +18,13 @@ import ( "fmt" "strings" - "github.com/dolthub/dolt/go/libraries/doltcore/sqle" "github.com/dolthub/go-mysql-server/enginetest/queries" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/expression" "github.com/dolthub/go-mysql-server/sql/plan" "github.com/dolthub/go-mysql-server/sql/types" + + "github.com/dolthub/dolt/go/libraries/doltcore/sqle" ) var ViewsWithAsOfScriptTest = queries.ScriptTest{ @@ -2498,7 +2499,7 @@ var LogTableFunctionScriptTests = []queries.ScriptTest{ "call dolt_add('.')", "set @Commit1 = '';", "call dolt_commit_hash_out(@Commit1, '-am', 'creating table t');", - + "insert into t values(1, 'one', 'two'), (2, 'two', 'three');", "set @Commit2 = '';", "call dolt_commit_hash_out(@Commit2, '-am', 'inserting into t');", From e685186b3614fd56c6d0e2f1fa9ea46ed5ac78da Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 6 Jun 2023 17:16:23 -0700 Subject: [PATCH 161/167] Test fixes --- go/libraries/doltcore/sqle/enginetest/dolt_server_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index 17a3b14185..88da172825 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -235,11 +235,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ select name from dolt_branches;", - ExpectedErrStr: "Error 1105: database not found: dolt/branch1", + ExpectedErrStr: "Error 1105: branch not found", }, { Query: "/* client a */ CALL DOLT_CHECKOUT('main');", - ExpectedErrStr: "Error 1105: database not found: dolt/branch1", + ExpectedErrStr: "Error 1105: Could not load database dolt", }, { Query: "/* client a */ USE dolt/main;", @@ -284,11 +284,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { Query: "/* client a */ select name from dolt_branches;", - ExpectedErrStr: "Error 1105: database not found: dolt/branch1", + Expected: []sql.Row{{"branch1"}, {"main"}}, }, { Query: "/* client a */ CALL DOLT_CHECKOUT('main');", - ExpectedErrStr: "Error 1105: database not found: dolt/branch1", + Expected: []sql.Row{{0}}, }, { Query: "/* client a */ USE dolt/main;", From 15dae477199298ee94f3ddfc1296c8b60fdae92f Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 7 Jun 2023 08:02:47 -0700 Subject: [PATCH 162/167] Note --- go/libraries/doltcore/sqle/enginetest/dolt_server_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index 88da172825..1070216a2b 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -283,6 +283,7 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ Expected: []sql.Row{{"main"}}, }, { + // client a still sees the branches and can use them because it's in a transaction Query: "/* client a */ select name from dolt_branches;", Expected: []sql.Row{{"branch1"}, {"main"}}, }, From 2dd36015045aab65dc707e956a8274d4af45aa96 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 7 Jun 2023 08:35:38 -0700 Subject: [PATCH 163/167] Fixed bats test --- integration-tests/bats/remotes-sql-server.bats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/bats/remotes-sql-server.bats b/integration-tests/bats/remotes-sql-server.bats index 230b2c9c57..2703173bcb 100644 --- a/integration-tests/bats/remotes-sql-server.bats +++ b/integration-tests/bats/remotes-sql-server.bats @@ -499,7 +499,7 @@ teardown() { run dolt sql-client --use-db repo2/feature -P $PORT -u dolt -q "select active_branch()" [ $status -eq 1 ] - [[ "$output" =~ "database not found: repo2/feature" ]] || false + [[ "$output" =~ "'feature' matched multiple remote tracking branches" ]] || false run grep "'feature' matched multiple remote tracking branches" server_log.txt [ "${#lines[@]}" -ne 0 ] From ab31d5c826bfa627a4684fde710ce329f34ff594 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 7 Jun 2023 08:55:21 -0700 Subject: [PATCH 164/167] Fixed tests --- .../mysql-client-tests/node/workbenchTests/databases.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/integration-tests/mysql-client-tests/node/workbenchTests/databases.js b/integration-tests/mysql-client-tests/node/workbenchTests/databases.js index ef08912a4f..4d78d06757 100644 --- a/integration-tests/mysql-client-tests/node/workbenchTests/databases.js +++ b/integration-tests/mysql-client-tests/node/workbenchTests/databases.js @@ -19,7 +19,6 @@ export const databaseTests = [ q: `SHOW DATABASES`, res: [ { Database: `${dbName}` }, - { Database: `${dbName}/main` }, { Database: "information_schema" }, { Database: "mysql" }, ], @@ -40,7 +39,6 @@ export const databaseTests = [ q: `SHOW DATABASES`, res: [ { Database: `${dbName}` }, - { Database: `${dbName}/main` }, { Database: "information_schema" }, { Database: "mysql" }, { Database: "new_db" }, From 9235bade1aac2b4377a4da1b12605cdced97037e Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 7 Jun 2023 09:04:45 -0700 Subject: [PATCH 165/167] gms@main --- go/go.mod | 2 +- go/go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go/go.mod b/go/go.mod index 23b41577ba..ef1f825e64 100644 --- a/go/go.mod +++ b/go/go.mod @@ -59,7 +59,7 @@ require ( github.com/cespare/xxhash v1.1.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.15.1-0.20230606174340-20dde39da840 + github.com/dolthub/go-mysql-server v0.15.1-0.20230607160120-febad34dabd4 github.com/dolthub/swiss v0.1.0 github.com/goccy/go-json v0.10.2 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 diff --git a/go/go.sum b/go/go.sum index d45196d791..4d13cdbc99 100644 --- a/go/go.sum +++ b/go/go.sum @@ -170,6 +170,8 @@ github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e h1:kPsT4a47cw github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168= github.com/dolthub/go-mysql-server v0.15.1-0.20230606174340-20dde39da840 h1:LNrH1zxCioDcpTMkTV/cr3LI4AlyxrmILI17OUbijUU= github.com/dolthub/go-mysql-server v0.15.1-0.20230606174340-20dde39da840/go.mod h1:TP8QrAsULBEK7nP0BHRSfZ9l8oiAeaRzIREHVk2wnz0= +github.com/dolthub/go-mysql-server v0.15.1-0.20230607160120-febad34dabd4 h1:NT1otNLjn/eIWU4p4VV3jGUSiGrVGwc9qAdcSeQoLPg= +github.com/dolthub/go-mysql-server v0.15.1-0.20230607160120-febad34dabd4/go.mod h1:TP8QrAsULBEK7nP0BHRSfZ9l8oiAeaRzIREHVk2wnz0= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto= github.com/dolthub/jsonpath v0.0.2-0.20230525180605-8dc13778fd72 h1:NfWmngMi1CYUWU4Ix8wM+USEhjc+mhPlT9JUR/anvbQ= From 6688243ea598b065aa88c11086e54b2c32f42e9e Mon Sep 17 00:00:00 2001 From: zachmu Date: Wed, 7 Jun 2023 16:14:47 +0000 Subject: [PATCH 166/167] [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh --- go/go.sum | 2 -- go/libraries/doltcore/sqle/enginetest/dolt_server_test.go | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/go/go.sum b/go/go.sum index 4d13cdbc99..1988b14a72 100644 --- a/go/go.sum +++ b/go/go.sum @@ -168,8 +168,6 @@ 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-20230524105445-af7e7991c97e h1:kPsT4a47cw1+y/N5SSCkma7FhAPw7KeGmD6c9PBZW9Y= github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168= -github.com/dolthub/go-mysql-server v0.15.1-0.20230606174340-20dde39da840 h1:LNrH1zxCioDcpTMkTV/cr3LI4AlyxrmILI17OUbijUU= -github.com/dolthub/go-mysql-server v0.15.1-0.20230606174340-20dde39da840/go.mod h1:TP8QrAsULBEK7nP0BHRSfZ9l8oiAeaRzIREHVk2wnz0= github.com/dolthub/go-mysql-server v0.15.1-0.20230607160120-febad34dabd4 h1:NT1otNLjn/eIWU4p4VV3jGUSiGrVGwc9qAdcSeQoLPg= github.com/dolthub/go-mysql-server v0.15.1-0.20230607160120-febad34dabd4/go.mod h1:TP8QrAsULBEK7nP0BHRSfZ9l8oiAeaRzIREHVk2wnz0= github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514= diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go index 1070216a2b..1f8a44ee2c 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_server_test.go @@ -284,11 +284,11 @@ var DoltBranchMultiSessionScriptTests = []queries.ScriptTest{ }, { // client a still sees the branches and can use them because it's in a transaction - Query: "/* client a */ select name from dolt_branches;", + Query: "/* client a */ select name from dolt_branches;", Expected: []sql.Row{{"branch1"}, {"main"}}, }, { - Query: "/* client a */ CALL DOLT_CHECKOUT('main');", + Query: "/* client a */ CALL DOLT_CHECKOUT('main');", Expected: []sql.Row{{0}}, }, { From 49e0923cdd2983a6db008573495cd03b4b70d948 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Wed, 7 Jun 2023 12:25:38 -0700 Subject: [PATCH 167/167] updating tests --- .../mysql-client-tests/node/workbenchTests/table.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integration-tests/mysql-client-tests/node/workbenchTests/table.js b/integration-tests/mysql-client-tests/node/workbenchTests/table.js index c9972e5738..332aec248b 100644 --- a/integration-tests/mysql-client-tests/node/workbenchTests/table.js +++ b/integration-tests/mysql-client-tests/node/workbenchTests/table.js @@ -74,7 +74,7 @@ export const tableTests = [ FROM information_schema.statistics WHERE table_schema=:tableSchema AND table_name=:tableName AND index_name!="PRIMARY" GROUP BY index_name;`, - p: { tableSchema: `${dbName}/main`, tableName: "test" }, + p: { tableSchema: `${dbName}`, tableName: "test" }, res: [ { TABLE_NAME: "test", @@ -122,19 +122,19 @@ export const tableTests = [ }, { q: `SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_name=:tableName AND table_schema=:tableSchema AND referenced_table_schema IS NOT NULL`, - p: { tableName: "test_info", tableSchema: `${dbName}/main` }, + p: { tableName: "test_info", tableSchema: `${dbName}` }, res: [ { CONSTRAINT_CATALOG: "def", - CONSTRAINT_SCHEMA: `${dbName}/main`, + CONSTRAINT_SCHEMA: `${dbName}`, CONSTRAINT_NAME: "s7utamh8", TABLE_CATALOG: "def", - TABLE_SCHEMA: `${dbName}/main`, + TABLE_SCHEMA: `${dbName}`, TABLE_NAME: "test_info", COLUMN_NAME: "test_pk", ORDINAL_POSITION: 1, POSITION_IN_UNIQUE_CONSTRAINT: 1, - REFERENCED_TABLE_SCHEMA: `${dbName}/main`, + REFERENCED_TABLE_SCHEMA: `${dbName}`, REFERENCED_TABLE_NAME: "test", REFERENCED_COLUMN_NAME: "pk", },