diff --git a/go/cmd/dolt/commands/cvcmds/verify_constraints.go b/go/cmd/dolt/commands/cvcmds/verify_constraints.go index ec728632389..cb4fd5b203d 100644 --- a/go/cmd/dolt/commands/cvcmds/verify_constraints.go +++ b/go/cmd/dolt/commands/cvcmds/verify_constraints.go @@ -125,7 +125,7 @@ func (cmd VerifyConstraintsCmd) Exec(ctx context.Context, commandStr string, arg defer sql.SessionCommandEnd(sqlCtx.Session) sqlCtx.SetCurrentDatabase(dbName) - tableResolver, err := dsess.GetTableResolver(sqlCtx) + tableResolver, err := dsess.GetTableResolver(sqlCtx, dbName) if err != nil { cli.PrintErrln(errhand.VerboseErrorFromError(err)) return 1 diff --git a/go/cmd/dolt/commands/schcmds/copy-tags.go b/go/cmd/dolt/commands/schcmds/copy-tags.go index 3bbb15a60a4..17502864ae2 100644 --- a/go/cmd/dolt/commands/schcmds/copy-tags.go +++ b/go/cmd/dolt/commands/schcmds/copy-tags.go @@ -102,7 +102,7 @@ func (cmd CopyTagsCmd) Exec(ctx context.Context, commandStr string, args []strin } sqlCtx := queryist.Context - tableResolver, err := dsess.GetTableResolver(sqlCtx) + tableResolver, err := dsess.GetTableResolver(sqlCtx, sqlCtx.GetCurrentDatabase()) if err != nil { cli.PrintErrln(errhand.VerboseErrorFromError(err)) return 1 diff --git a/go/libraries/doltcore/cherry_pick/cherry_pick.go b/go/libraries/doltcore/cherry_pick/cherry_pick.go index f7c64b3726d..c8012218a23 100644 --- a/go/libraries/doltcore/cherry_pick/cherry_pick.go +++ b/go/libraries/doltcore/cherry_pick/cherry_pick.go @@ -249,7 +249,7 @@ func cherryPick(ctx *sql.Context, dSess *dsess.DoltSession, roots doltdb.Roots, return nil, "", nil, err } - tableResolver, err := dsess.GetTableResolver(ctx) + tableResolver, err := dsess.GetTableResolver(ctx, dbName) if err != nil { return nil, "", nil, err } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go b/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go index c4f30fac161..50adad1323a 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go @@ -318,13 +318,13 @@ func resolveNomsConflicts(ctx *sql.Context, opts editor.Options, tbl *doltdb.Tab return resolvePkConflicts(ctx, opts, tbl, tblName, sch, conflicts) } -func validateConstraintViolations(ctx *sql.Context, before, after doltdb.RootValue, table doltdb.TableName) error { +func validateConstraintViolations(ctx *sql.Context, dbName string, before, after doltdb.RootValue, table doltdb.TableName) error { tables, err := after.GetTableNames(ctx, table.Schema, true) if err != nil { return err } - tableResolver, err := dsess.GetTableResolver(ctx) + tableResolver, err := dsess.GetTableResolver(ctx, dbName) if err != nil { return err } @@ -413,7 +413,7 @@ func ResolveSchemaConflicts(ctx *sql.Context, ddb *doltdb.DoltDB, ws *doltdb.Wor return ws.WithWorkingRoot(root).WithUnmergableTables(unmerged).WithMergedTables(merged), nil } -func ResolveDataConflictsForTable(ctx *sql.Context, root doltdb.RootValue, tblName doltdb.TableName, ours bool, getEditorOpts func() (editor.Options, error)) (doltdb.RootValue, bool, error) { +func ResolveDataConflictsForTable(ctx *sql.Context, dbName string, root doltdb.RootValue, tblName doltdb.TableName, ours bool, getEditorOpts func() (editor.Options, error)) (doltdb.RootValue, bool, error) { tbl, ok, err := root.GetTable(ctx, tblName) if err != nil { return nil, false, err @@ -463,7 +463,7 @@ func ResolveDataConflictsForTable(ctx *sql.Context, root doltdb.RootValue, tblNa return nil, false, err } - err = validateConstraintViolations(ctx, root, newRoot, tblName) + err = validateConstraintViolations(ctx, dbName, root, newRoot, tblName) if err != nil { return nil, false, err } @@ -485,7 +485,7 @@ func ResolveDataConflicts(ctx *sql.Context, dSess *dsess.DoltSession, root doltd } for _, tblName := range tblNames { - newRoot, hasConflicts, err := ResolveDataConflictsForTable(ctx, root, tblName, ours, getEditorOpts) + newRoot, hasConflicts, err := ResolveDataConflictsForTable(ctx, dbName, root, tblName, ours, getEditorOpts) if err != nil { return err } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go index b695f695603..6a0471163cd 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_merge.go @@ -329,7 +329,7 @@ func executeMerge( opts editor.Options, workingDiffs map[doltdb.TableName]hash.Hash, ) (*doltdb.WorkingSet, error) { - sqlDB, err := dsess.GetTableResolver(ctx) + sqlDB, err := dsess.GetTableResolver(ctx, dbName) if err != nil { return nil, err } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_revert.go b/go/libraries/doltcore/sqle/dprocedures/dolt_revert.go index 67dc61504a6..e6aaaaab69c 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_revert.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_revert.go @@ -41,7 +41,7 @@ func doltRevert(ctx *sql.Context, args ...string) (sql.RowIter, error) { func doDoltRevert(ctx *sql.Context, args []string) (int, error) { dbName := ctx.GetCurrentDatabase() dSess := dsess.DSessFromSess(ctx.Session) - tableResolver, err := dsess.GetTableResolver(ctx) + tableResolver, err := dsess.GetTableResolver(ctx, dbName) if err != nil { return 1, err } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_stash.go b/go/libraries/doltcore/sqle/dprocedures/dolt_stash.go index 5be6b449cad..74c5c76d357 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_stash.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_stash.go @@ -88,11 +88,11 @@ func doDoltStash(ctx *sql.Context, args []string) (int, error) { } err = doStashPush(ctx, dSess, dbData, roots, apr, stashName) case "pop": - err = doStashPop(ctx, dbData, stashName, idx) + err = doStashPop(ctx, dbName, dbData, stashName, idx) case "drop": err = doStashDrop(ctx, dbData, stashName, idx) case "apply": - err = doStashApply(ctx, dbData, stashName, idx) + err = doStashApply(ctx, dbName, dbData, stashName, idx) case "clear": if apr.NArg() > 2 { // Clear does not take extra arguments return cmdFailure, fmt.Errorf("error: invalid arguments. Clear takes only subcommand and stash name") @@ -160,8 +160,8 @@ func doStashPush(ctx *sql.Context, dSess *dsess.DoltSession, dbData env.DbData[* return updateWorkingSetFromRoots(ctx, dbData, roots) } -func doStashPop(ctx *sql.Context, dbData env.DbData[*sql.Context], stashName string, idx int) error { - headCommit, result, meta, err := handleMerge(ctx, dbData, stashName, idx) +func doStashPop(ctx *sql.Context, dbName string, dbData env.DbData[*sql.Context], stashName string, idx int) error { + headCommit, result, meta, err := handleMerge(ctx, dbName, dbData, stashName, idx) if err != nil { return err } @@ -191,8 +191,8 @@ func doStashPop(ctx *sql.Context, dbData env.DbData[*sql.Context], stashName str return dbData.Ddb.RemoveStashAtIdx(ctx, idx, stashName) } -func doStashApply(ctx *sql.Context, dbData env.DbData[*sql.Context], stashName string, idx int) error { - headCommit, result, meta, err := handleMerge(ctx, dbData, stashName, idx) +func doStashApply(ctx *sql.Context, dbName string, dbData env.DbData[*sql.Context], stashName string, idx int) error { + headCommit, result, meta, err := handleMerge(ctx, dbName, dbData, stashName, idx) if err != nil { return err } @@ -465,7 +465,7 @@ func gatherCommitData(ctx *sql.Context, dbData env.DbData[*sql.Context]) (*doltd } -func handleMerge(ctx *sql.Context, dbData env.DbData[*sql.Context], stashName string, idx int) (*doltdb.Commit, *merge.Result, *datas.StashMeta, error) { +func handleMerge(ctx *sql.Context, dbName string, dbData env.DbData[*sql.Context], stashName string, idx int) (*doltdb.Commit, *merge.Result, *datas.StashMeta, error) { headRef, err := dbData.Rsr.CWBHeadRef(ctx) if err != nil { return nil, nil, nil, err @@ -515,7 +515,7 @@ func handleMerge(ctx *sql.Context, dbData env.DbData[*sql.Context], stashName st return nil, nil, nil, err } - tableResolver, err := dsess.GetTableResolver(ctx) + tableResolver, err := dsess.GetTableResolver(ctx, dbName) if err != nil { return nil, nil, nil, err } diff --git a/go/libraries/doltcore/sqle/dprocedures/dolt_verify_constraints.go b/go/libraries/doltcore/sqle/dprocedures/dolt_verify_constraints.go index 3f9ba36b157..1701a2fd91c 100644 --- a/go/libraries/doltcore/sqle/dprocedures/dolt_verify_constraints.go +++ b/go/libraries/doltcore/sqle/dprocedures/dolt_verify_constraints.go @@ -82,7 +82,7 @@ func doDoltConstraintsVerify(ctx *sql.Context, args []string) (int, error) { } // Check for all non-FK constraint violations - newRoot, tablesWithViolations, err := calculateViolations(ctx, workingRoot, comparingRoot, tableSet) + newRoot, tablesWithViolations, err := calculateViolations(ctx, dbName, workingRoot, comparingRoot, tableSet) if err != nil { return 1, err } @@ -110,7 +110,7 @@ func doDoltConstraintsVerify(ctx *sql.Context, args []string) (int, error) { // tables in |tableSet|. Returns the new root with the violations, and a set of table names that have violations. // Note that constraint violations detected for ALL existing tables will be stored in the dolt_constraint_violations // tables, but the returned set of table names will be a subset of |tableSet|. -func calculateViolations(ctx *sql.Context, workingRoot, comparingRoot doltdb.RootValue, tableSet *doltdb.TableNameSet) (doltdb.RootValue, *doltdb.TableNameSet, error) { +func calculateViolations(ctx *sql.Context, dbName string, workingRoot, comparingRoot doltdb.RootValue, tableSet *doltdb.TableNameSet) (doltdb.RootValue, *doltdb.TableNameSet, error) { var recordViolationsForTables map[doltdb.TableName]struct{} = nil if tableSet.Size() > 0 { recordViolationsForTables = make(map[doltdb.TableName]struct{}) @@ -119,7 +119,7 @@ func calculateViolations(ctx *sql.Context, workingRoot, comparingRoot doltdb.Roo } } - tableResolver, err := dsess.GetTableResolver(ctx) + tableResolver, err := dsess.GetTableResolver(ctx, dbName) if err != nil { return nil, nil, err } diff --git a/go/libraries/doltcore/sqle/dsess/session.go b/go/libraries/doltcore/sqle/dsess/session.go index 787e7eff70f..a4c781f1dfa 100644 --- a/go/libraries/doltcore/sqle/dsess/session.go +++ b/go/libraries/doltcore/sqle/dsess/session.go @@ -156,8 +156,7 @@ func DSessFromSess(sess sql.Session) *DoltSession { return sess.(*DoltSession) } -func GetTableResolver(ctx *sql.Context) (doltdb.TableResolver, error) { - dbName := ctx.GetCurrentDatabase() +func GetTableResolver(ctx *sql.Context, dbName string) (doltdb.TableResolver, error) { dSess := DSessFromSess(ctx.Session) if dbName == "" { // If no database is selected, there's no situation where we need to resolve nonlocal tables. @@ -542,8 +541,9 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) (e message = trimmedString } + dbName := ctx.GetCurrentDatabase() var pendingCommit *doltdb.PendingCommit - pendingCommit, err = d.PendingCommitAllStaged(ctx, dirtyBranchState, actions.CommitStagedProps{ + pendingCommit, err = d.PendingCommitAllStaged(ctx, dbName, dirtyBranchState, actions.CommitStagedProps{ Message: message, Date: ctx.QueryTime(), AllowEmpty: false, @@ -560,7 +560,7 @@ func (d *DoltSession) CommitTransaction(ctx *sql.Context, tx sql.Transaction) (e return d.commitWorkingSet(ctx, dirtyBranchState, tx) } - _, err = d.DoltCommit(ctx, ctx.GetCurrentDatabase(), tx, pendingCommit) + _, err = d.DoltCommit(ctx, dbName, tx, pendingCommit) return err } else { return d.commitWorkingSet(ctx, dirtyBranchState, tx) @@ -669,19 +669,19 @@ func (d *DoltSession) DoltCommit( if err != nil { return nil, nil, err } - - return ws, commit, err + return ws, commit, nil } c, err := d.commitCurrentHead(ctx, dbName, tx, commitFunc) + if err != nil { + return nil, err + } - if err == nil { - branch, b, e := d.CurrentHead(ctx, dbName) - if e == nil && b { - doltdb.BranchActivityWriteEvent(ctx, dbName, branch) - } + branch, b, e := d.CurrentHead(ctx, dbName) + if e == nil && b { + doltdb.BranchActivityWriteEvent(ctx, dbName, branch) } - return c, err + return c, nil } // doCommitFunc is a function to write to the database, which involves updating the working set and potentially @@ -726,7 +726,7 @@ func (d *DoltSession) commitCurrentHead(ctx *sql.Context, dbName string, tx sql. } // 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, branchState *branchState, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { +func (d *DoltSession) PendingCommitAllStaged(ctx *sql.Context, dbName string, branchState *branchState, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { roots := branchState.roots() var err error @@ -735,7 +735,7 @@ func (d *DoltSession) PendingCommitAllStaged(ctx *sql.Context, branchState *bran return nil, err } - return d.newPendingCommit(ctx, branchState, roots, props) + return d.newPendingCommit(ctx, dbName, branchState, roots, props) } // NewPendingCommit returns a new |doltdb.PendingCommit| for the database named, using the roots given, adding any @@ -755,12 +755,12 @@ func (d *DoltSession) NewPendingCommit( return nil, fmt.Errorf("session state for database %s not found", dbName) } - return d.newPendingCommit(ctx, branchState, roots, props) + return d.newPendingCommit(ctx, dbName, 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) { +func (d *DoltSession) newPendingCommit(ctx *sql.Context, dbName string, branchState *branchState, roots doltdb.Roots, props actions.CommitStagedProps) (*doltdb.PendingCommit, error) { headCommit := branchState.headCommit if branchState.WorkingSet() == nil { @@ -797,7 +797,7 @@ func (d *DoltSession) newPendingCommit(ctx *sql.Context, branchState *branchStat } } - tableResolver, err := GetTableResolver(ctx) + tableResolver, err := GetTableResolver(ctx, dbName) if err != nil { return nil, err } diff --git a/go/libraries/doltcore/sqle/dsess/transactions.go b/go/libraries/doltcore/sqle/dsess/transactions.go index 492680860a3..f9f40cae04e 100644 --- a/go/libraries/doltcore/sqle/dsess/transactions.go +++ b/go/libraries/doltcore/sqle/dsess/transactions.go @@ -175,6 +175,7 @@ func (tx *DoltTransaction) Commit(ctx *sql.Context, workingSet *doltdb.WorkingSe // transactionWrite is the logic to write an updated working set (and optionally a commit) to the database type transactionWrite func(ctx *sql.Context, + dbName string, tx *DoltTransaction, // the transaction being written doltDb *doltdb.DoltDB, // the database to write to startState *doltdb.WorkingSet, // the starting working set @@ -186,6 +187,7 @@ 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, + dbName string, tx *DoltTransaction, // the transaction being written doltDb *doltdb.DoltDB, // the database to write to startState *doltdb.WorkingSet, // the starting working set @@ -240,7 +242,7 @@ func doltCommit(ctx *sql.Context, // is the value which we are trying to commit. start := time.Now() - tableResolver, err := GetTableResolver(ctx) + tableResolver, err := GetTableResolver(ctx, dbName) if err != nil { return nil, nil, err } @@ -276,6 +278,7 @@ func doltCommit(ctx *sql.Context, // txCommit is a transactionWrite function that updates the working set func txCommit(ctx *sql.Context, + dbName string, tx *DoltTransaction, // the transaction being written doltDb *doltdb.DoltDB, // the database to write to _ *doltdb.WorkingSet, // the starting working set @@ -440,7 +443,7 @@ func (tx *DoltTransaction) doCommit( } var newCommit *doltdb.Commit - workingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, workingSet, existingWSHash, mergeOpts) + workingSet, newCommit, err = writeFn(ctx, dbName, tx, startPoint.db, startState, commit, workingSet, existingWSHash, mergeOpts) if err == datas.ErrOptimisticLockFailed { // this is effectively a `continue` in the loop return nil, nil, nil @@ -453,7 +456,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, mergeOpts) + mergedWorkingSet, err := tx.mergeRoots(ctx, dbName, startState, existingWs, workingSet, mergeOpts) if err != nil { return nil, nil, err } @@ -465,7 +468,7 @@ func (tx *DoltTransaction) doCommit( } var newCommit *doltdb.Commit - mergedWorkingSet, newCommit, err = writeFn(ctx, tx, startPoint.db, startState, commit, mergedWorkingSet, existingWSHash, mergeOpts) + mergedWorkingSet, newCommit, err = writeFn(ctx, dbName, tx, startPoint.db, startState, commit, mergedWorkingSet, existingWSHash, mergeOpts) if err == datas.ErrOptimisticLockFailed { // this is effectively a `continue` in the loop return nil, nil, nil @@ -492,13 +495,14 @@ 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, + dbName string, startState *doltdb.WorkingSet, existingWorkingSet *doltdb.WorkingSet, workingSet *doltdb.WorkingSet, mergeOpts editor.Options, ) (*doltdb.WorkingSet, error) { - tableResolver, err := GetTableResolver(ctx) + tableResolver, err := GetTableResolver(ctx, dbName) if err != nil { return nil, err } diff --git a/integration-tests/go-sql-server-driver/tests/sql-server-orig.yaml b/integration-tests/go-sql-server-driver/tests/sql-server-orig.yaml index 633d2bba794..b6cfae663fd 100644 --- a/integration-tests/go-sql-server-driver/tests/sql-server-orig.yaml +++ b/integration-tests/go-sql-server-driver/tests/sql-server-orig.yaml @@ -396,6 +396,23 @@ tests: queries: - exec: "INSERT INTO t1 VALUES (1, 1),(2, 2)" error_match: "table not found" +- name: create a collated database connected to a non-dolt database + # Creating a collated database currently creates a new Dolt commit + # on the `main` branch of the created database. In the past there + # was a bug which used ctx.GetCurrentDatabase() in some code paths + # to attempt to create this database, which made things fail if + # the current database was a non-Dolt database (like mysql). + repos: + - name: repo1 + server: + args: ["--port", "{{get_port \"server1\"}}"] + dynamic_port: server1 + connections: + - on: repo1 + queries: + - exec: "USE mysql" + - exec: "CREATE DATABASE testdb COLLATE utf8mb4_unicode_ci" + - exec: "USE testdb" - name: dolt_gc succeeds as first write on existing database without a journal after chunk journal is enabled multi_repos: - name: server1