From adcf3c10f3a409a99b6453bc879d6f7cb327f1b7 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Fri, 17 Nov 2023 14:24:02 -0800 Subject: [PATCH 01/17] tests for dolt reflog --- integration-tests/bats/reflog.bats | 215 ++++++++++++++++++++++--- integration-tests/bats/sql-reflog.bats | 57 +++++++ 2 files changed, 252 insertions(+), 20 deletions(-) mode change 100644 => 100755 integration-tests/bats/reflog.bats create mode 100644 integration-tests/bats/sql-reflog.bats diff --git a/integration-tests/bats/reflog.bats b/integration-tests/bats/reflog.bats old mode 100644 new mode 100755 index 38d5a7e34e..d8906f4794 --- a/integration-tests/bats/reflog.bats +++ b/integration-tests/bats/reflog.bats @@ -1,45 +1,32 @@ #!/usr/bin/env bats load $BATS_TEST_DIRNAME/helper/common.bash +setup() { + setup_common +} + teardown() { assert_feature_version teardown_common } -# Asserts that when DOLT_DISABLE_REFLOG is set, the dolt_reflog() table -# function returns an empty result set with no error. +# Asserts that when DOLT_DISABLE_REFLOG is set, dolt reflog returns nothing with no error. @test "reflog: disabled with DOLT_DISABLE_REFLOG" { export DOLT_DISABLE_REFLOG=true - setup_common dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" dolt commit --allow-empty -m "test commit 1" - run dolt sql -q "select * from dolt_reflog();" + run dolt reflog [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 0 ] } -# Sanity check for the most basic case of querying the Dolt reflog -@test "reflog: enabled by default" { - setup_common - dolt sql -q "create table t (i int primary key, j int);" - dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; - dolt commit -Am "initial commit" - - run dolt sql -q "select * from dolt_reflog();" - [ "$status" -eq 0 ] - [ "${#lines[@]}" -eq 6 ] - [[ "$output" =~ "initial commit" ]] || false - [[ "$output" =~ "Initialize data repository" ]] || false -} - # Asserts that when DOLT_REFLOG_RECORD_LIMIT has been set, the reflog only contains the # most recent entries and is limited by the env var's value. @test "reflog: set DOLT_REFLOG_RECORD_LIMIT" { export DOLT_REFLOG_RECORD_LIMIT=2 - setup_common dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" @@ -47,10 +34,198 @@ teardown() { dolt commit --allow-empty -m "test commit 2" # Only the most recent two ref changes should appear in the log - run dolt sql -q "select * from dolt_reflog();" + run dolt reflog [ "$status" -eq 0 ] [[ "$output" =~ "test commit 1" ]] || false [[ "$output" =~ "test commit 2" ]] || false [[ ! "$output" =~ "initial commit" ]] || false [[ ! "$output" =~ "Initialize data repository" ]] || false } + +@test "reflog: simple reflog" { + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + + run dolt reflog + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(HEAD -> main) HEAD@{0}: initial commit" ]] || false + [[ "$out" =~ "HEAD@{1}: Initialize data repository" ]] || false +} + +@test "reflog: reflog with ref given" { + dolt sql < main) HEAD@{0}: inserting row 1" ]] || false + [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false + [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + + # ref is case-insensitive + run dolt reflog rEFs/heAdS/MAIN + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 3 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(HEAD -> main) HEAD@{0}: inserting row 1" ]] || false + [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false + [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + + run dolt reflog main + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 3 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(HEAD -> main) HEAD@{0}: inserting row 1" ]] || false + [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false + [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + + # ref is case-insensitive + run dolt reflog MaIn + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 3 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(HEAD -> main) HEAD@{0}: inserting row 1" ]] || false + [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false + [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + + run dolt reflog refs/heads/branch1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 3 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(branch1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 2" ]] || false + [[ "$out" =~ "HEAD@{2}: inserting row 1" ]] || false + + run dolt reflog branch1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 3 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(branch1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 2" ]] || false + [[ "$out" =~ "HEAD@{2}: inserting row 1" ]] || false + + run dolt reflog refs/tags/tag1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + + # ref is case-insensitive + run dolt reflog Refs/tAGs/TaG1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + + run dolt reflog tag1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + + # ref is case-insensitive + run dolt reflog TAg1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + + dolt branch -D branch1 + + run dolt reflog branch1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 3 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(branch1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 2" ]] || false + [[ "$out" =~ "HEAD@{2}: inserting row 1" ]] || false + + dolt tag -d tag1 + run dolt reflog tag1 + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false +} + +@test "reflog: garbage collection with no newgen data" { + run dolt reflog + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 1 ] + out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$out" =~ "(HEAD -> main) HEAD@{0}: Initialize data repository" ]] || false + + dolt gc + + run dolt reflog + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 0 ] +} + +@test "reflog: garbage collection with newgen data" { + dolt sql < main) HEAD@{0}: inserting row 2" ]] || false + [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + [[ "$out" =~ "HEAD@{2}: creating table t1" ]] || false + [[ "$out" =~ "HEAD@{3}: Initialize data repository" ]] || false + + dolt gc + + run dolt reflog main + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 0 ] +} + +@test "reflog: too many arguments given" { + run dolt reflog foo bar + [ "$status" -eq 1 ] + [[ "$output" =~ "error: reflog has too many positional arguments" ]] +} + +@test "reflog: unknown ref returns nothing" { + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + + run dolt reflog foo + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 0 ] +} diff --git a/integration-tests/bats/sql-reflog.bats b/integration-tests/bats/sql-reflog.bats new file mode 100644 index 0000000000..bac628f016 --- /dev/null +++ b/integration-tests/bats/sql-reflog.bats @@ -0,0 +1,57 @@ +#!/usr/bin/env bats +load $BATS_TEST_DIRNAME/helper/common.bash + +setup() { + setup_common +} + +teardown() { + assert_feature_version + teardown_common +} + +# Asserts that when DOLT_DISABLE_REFLOG is set, the dolt_reflog() table +# function returns an empty result set with no error. +@test "sql-reflog: disabled with DOLT_DISABLE_REFLOG" { + export DOLT_DISABLE_REFLOG=true + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + dolt commit --allow-empty -m "test commit 1" + + run dolt sql -q "select * from dolt_reflog();" + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 0 ] +} + +# Sanity check for the most basic case of querying the Dolt reflog +@test "sql-reflog: enabled by default" { + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + + run dolt sql -q "select * from dolt_reflog();" + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 6 ] + [[ "$output" =~ "initial commit" ]] || false + [[ "$output" =~ "Initialize data repository" ]] || false +} + +# Asserts that when DOLT_REFLOG_RECORD_LIMIT has been set, the reflog only contains the +# most recent entries and is limited by the env var's value. +@test "sql-reflog: set DOLT_REFLOG_RECORD_LIMIT" { + export DOLT_REFLOG_RECORD_LIMIT=2 + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + dolt commit --allow-empty -m "test commit 1" + dolt commit --allow-empty -m "test commit 2" + + # Only the most recent two ref changes should appear in the log + run dolt sql -q "select * from dolt_reflog();" + [ "$status" -eq 0 ] + [[ "$output" =~ "test commit 1" ]] || false + [[ "$output" =~ "test commit 2" ]] || false + [[ ! "$output" =~ "initial commit" ]] || false + [[ ! "$output" =~ "Initialize data repository" ]] || false +} From fccec02c72f4135f39abe541bfb7feb17900fe3d Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Mon, 20 Nov 2023 16:06:35 -0800 Subject: [PATCH 02/17] basic dolt reflog implementation --- go/cmd/dolt/cli/arg_parser_helpers.go | 5 + go/cmd/dolt/commands/reflog.go | 189 ++++++++++++++++++ go/cmd/dolt/dolt.go | 1 + .../eventsapi/v1alpha1/event_constants.pb.go | 1 + .../eventsapi/v1alpha1/event_constants.proto | 1 + 5 files changed, 197 insertions(+) create mode 100644 go/cmd/dolt/commands/reflog.go diff --git a/go/cmd/dolt/cli/arg_parser_helpers.go b/go/cmd/dolt/cli/arg_parser_helpers.go index 9848beb391..2d15db07ee 100644 --- a/go/cmd/dolt/cli/arg_parser_helpers.go +++ b/go/cmd/dolt/cli/arg_parser_helpers.go @@ -280,6 +280,11 @@ func CreateCountCommitsArgParser() *argparser.ArgParser { return ap } +func CreateReflogArgParser() *argparser.ArgParser { + ap := argparser.NewArgParserWithMaxArgs("reflog", 1) + return ap +} + func CreateGlobalArgParser(name string) *argparser.ArgParser { ap := argparser.NewArgParserWithVariableArgs(name) if name == "dolt" { diff --git a/go/cmd/dolt/commands/reflog.go b/go/cmd/dolt/commands/reflog.go new file mode 100644 index 0000000000..9c633394e7 --- /dev/null +++ b/go/cmd/dolt/commands/reflog.go @@ -0,0 +1,189 @@ +// 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 commands + +import ( + "context" + "fmt" + "strings" + + "github.com/dolthub/dolt/go/cmd/dolt/cli" + "github.com/dolthub/dolt/go/cmd/dolt/errhand" + eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1" + "github.com/dolthub/dolt/go/libraries/doltcore/env" + "github.com/dolthub/dolt/go/libraries/utils/argparser" + "github.com/dolthub/dolt/go/store/util/outputpager" + "github.com/dolthub/go-mysql-server/sql" + "github.com/gocraft/dbr/v2" + "github.com/gocraft/dbr/v2/dialect" +) + +var reflogDocs = cli.CommandDocumentationContent{ + ShortDesc: "Shows a history of named refs", + LongDesc: `Shows the history of named refs (e.g. branches and tags), which is useful for understanding how a branch +or tag changed over time to reference different commits, particularly for information not surfaced through {{.EmphasisLeft}}dolt log{{.EmphasisRight}}. +The data from Dolt's reflog comes from [Dolt's journaling chunk store](https://www.dolthub.com/blog/2023-03-08-dolt-chunk-journal/). +This data is local to a Dolt database and never included when pushing, pulling, or cloning a Dolt database. This means when you clone a Dolt database, it will not have any reflog data until you perform operations that change what commit branches or tags reference. + +Dolt's reflog is similar to [Git's reflog](https://git-scm.com/docs/git-reflog), but there are a few differences: +- The Dolt reflog currently only supports named references, such as branches and tags, and not any of Git's special refs (e.g. {{.EmphasisLeft}}HEAD{{.EmphasisRight}}, {{.EmphasisLeft}}FETCH-HEAD{{.EmphasisRight}}, {{.EmphasisLeft}}MERGE-HEAD{{.EmphasisRight}}). +- The Dolt reflog can be queried for the log of references, even after a reference has been deleted. In Git, once a branch or tag is deleted, the reflog for that ref is also deleted and to find the last commit a branch or tag pointed to you have to use Git's special {{.EmphasisLeft}}HEAD{{.EmphasisRight}} reflog to find the commit, which can sometimes be challenging. Dolt makes this much easier by allowing you to see the history for a deleted ref so you can easily see the last commit a branch or tag pointed to before it was deleted.`, + Synopsis: []string{ + `{{.LessThan}}ref{{.GreaterThan}}`, + }, +} + +type ReflogCmd struct{} + +// Name is returns the name of the Dolt cli command. This is what is used on the command line to invoke the command +func (cmd ReflogCmd) Name() string { + return "reflog" +} + +// Description returns a description of the command +func (cmd ReflogCmd) Description() string { + return "Show history of named refs." +} + +// EventType returns the type of the event to log +func (cmd ReflogCmd) EventType() eventsapi.ClientEventType { + return eventsapi.ClientEventType_REFLOG +} + +func (cmd ReflogCmd) Docs() *cli.CommandDocumentation { + ap := cmd.ArgParser() + return cli.NewCommandDocumentation(reflogDocs, ap) +} + +func (cmd ReflogCmd) ArgParser() *argparser.ArgParser { + return cli.CreateReflogArgParser() +} + +func (cmd ReflogCmd) RequiresRepo() bool { + return false +} + +// Exec executes the command +func (cmd ReflogCmd) Exec(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv, cliCtx cli.CliContext) int { + ap := cmd.ArgParser() + help, usage := cli.HelpAndUsagePrinters(cli.CommandDocsForCommandString(commandStr, reflogDocs, ap)) + apr := cli.ParseArgsOrDie(ap, args, help) + + queryist, sqlCtx, closeFunc, err := cliCtx.QueryEngine(ctx) + if err != nil { + return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + if closeFunc != nil { + defer closeFunc() + } + + query, err := constructInterpolatedDoltReflogQuery(apr) + if err != nil { + return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + + rows, err := GetRowsForSql(queryist, sqlCtx, query) + if err != nil { + return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage) + } + + return printReflog(rows, queryist, sqlCtx) +} + +// constructInterpolatedDoltReflogQuery generates the sql query necessary to call the DOLT_REFLOG() function. +// Also interpolates this query to prevent sql injection +func constructInterpolatedDoltReflogQuery(apr *argparser.ArgParseResults) (string, error) { + var params []interface{} + refPlaceholder := "" + if apr.NArg() == 1 { + params = append(params, apr.Arg(0)) + refPlaceholder = "?" + } + + query := strings.Join([]string{"SELECT ref, commit_hash, commit_message FROM DOLT_REFLOG(", refPlaceholder, ")"}, "") + interpolatedQuery, err := dbr.InterpolateForDialect(query, params, dialect.MySQL) + if err != nil { + return "", err + } + + return interpolatedQuery, nil +} + +type ReflogInfo struct { + ref string + commitHash string + commitMessage string +} + +// printReflog takes a list of sql rows with columns ref, commit hash, commit message. Prints the reflog to stdout +func printReflog(rows []sql.Row, queryist cli.Queryist, sqlCtx *sql.Context) int { + var reflogInfo []ReflogInfo + + // Get the current branch + res, err := GetRowsForSql(queryist, sqlCtx, "SELECT active_branch()") + if err != nil { + return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), nil) + } + curBranch := res[0][0].(string) + + for _, row := range rows { + ref := row[0].(string) + commitHash := row[1].(string) + commitMessage := row[2].(string) + reflogInfo = append(reflogInfo, ReflogInfo{ref, commitHash, commitMessage}) + } + + reflogToStdOut(reflogInfo, curBranch) + + return 0 +} + +// reflogToStdOut takes a list of ReflogInfo and prints the reflog to stdout +func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) { + if cli.ExecuteWithStdioRestored == nil { + return + } + cli.ExecuteWithStdioRestored(func() { + pager := outputpager.Start() + defer pager.Stop() + + for pos, info := range reflogInfo { + // TODO: use short hash instead + line := []string{fmt.Sprintf("\033[33m%s\033[0m", info.commitHash)} // commit hash in yellow (33m) + + processedRef := processRefForReflog(info.ref, curBranch) + line = append(line, fmt.Sprintf("\033[33m(%s\033[33m)\033[0m", processedRef)) // () in yellow (33m) + line = append(line, fmt.Sprintf("HEAD@{%d}: %s\n", pos, info.commitMessage)) + pager.Writer.Write([]byte(strings.Join(line, " "))) + } + }) +} + +// processRefForReflog takes a full ref (e.g. refs/heads/master) or tag name and returns the ref name (e.g. master) with relevant decoration. +func processRefForReflog(fullRef string, curBranch string) string { + if strings.HasPrefix(fullRef, "refs/heads/") { + branch := strings.TrimPrefix(fullRef, "refs/heads/") + if branch == curBranch { + return fmt.Sprintf("\033[36;1mHEAD -> \033[32;1m%s\033[0m", branch) // HEAD in cyan (36;1), branch in green (32;1m) + } + return fmt.Sprintf("\033[32;1m%s\033[0m", branch) // branch in green (32;1m) + } else if strings.HasPrefix(fullRef, "refs/tags/") { + return fmt.Sprintf("\033[33mtag: %s\033[0m", strings.TrimPrefix(fullRef, "refs/tags/")) // tag in yellow (33m) + } else if strings.HasPrefix(fullRef, "refs/remotes/") { + return fmt.Sprintf("\033[31;1m%s\033[0m", strings.TrimPrefix(fullRef, "refs/remotes/")) // remote in red (31;1m) + } else { + return fullRef + } +} diff --git a/go/cmd/dolt/dolt.go b/go/cmd/dolt/dolt.go index 41b3ef5b28..b4db7c462b 100644 --- a/go/cmd/dolt/dolt.go +++ b/go/cmd/dolt/dolt.go @@ -123,6 +123,7 @@ var doltSubCommands = []cli.Command{ &commands.Assist{}, commands.ProfileCmd{}, commands.QueryDiff{}, + commands.ReflogCmd{}, } var commandsWithoutCliCtx = []cli.Command{ diff --git a/go/gen/proto/dolt/services/eventsapi/v1alpha1/event_constants.pb.go b/go/gen/proto/dolt/services/eventsapi/v1alpha1/event_constants.pb.go index 188068cfc1..c561933fea 100644 --- a/go/gen/proto/dolt/services/eventsapi/v1alpha1/event_constants.pb.go +++ b/go/gen/proto/dolt/services/eventsapi/v1alpha1/event_constants.pb.go @@ -155,6 +155,7 @@ const ( ClientEventType_STASH_POP ClientEventType = 60 ClientEventType_SHOW ClientEventType = 61 ClientEventType_PROFILE ClientEventType = 62 + ClientEventType_REFLOG ClientEventType = 63 ) // Enum value maps for ClientEventType. diff --git a/proto/dolt/services/eventsapi/v1alpha1/event_constants.proto b/proto/dolt/services/eventsapi/v1alpha1/event_constants.proto index 51e6db7703..d8d2088b29 100644 --- a/proto/dolt/services/eventsapi/v1alpha1/event_constants.proto +++ b/proto/dolt/services/eventsapi/v1alpha1/event_constants.proto @@ -92,6 +92,7 @@ enum ClientEventType { STASH_POP = 60; SHOW = 61; PROFILE = 62; + REFLOG = 63; } enum MetricID { From d3e7c7dfb310d6aaefbf9d8140c203db5b4efb8c Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Tue, 21 Nov 2023 10:44:03 -0800 Subject: [PATCH 03/17] add --all for reflog --- go/cmd/dolt/cli/arg_parser_helpers.go | 1 + go/cmd/dolt/commands/reflog.go | 18 +++++- .../doltcore/sqle/reflog_table_function.go | 56 +++++++++---------- 3 files changed, 44 insertions(+), 31 deletions(-) diff --git a/go/cmd/dolt/cli/arg_parser_helpers.go b/go/cmd/dolt/cli/arg_parser_helpers.go index 2d15db07ee..83e87cbfe3 100644 --- a/go/cmd/dolt/cli/arg_parser_helpers.go +++ b/go/cmd/dolt/cli/arg_parser_helpers.go @@ -282,6 +282,7 @@ func CreateCountCommitsArgParser() *argparser.ArgParser { func CreateReflogArgParser() *argparser.ArgParser { ap := argparser.NewArgParserWithMaxArgs("reflog", 1) + ap.SupportsFlag(AllFlag, "", "Show all refs") return ap } diff --git a/go/cmd/dolt/commands/reflog.go b/go/cmd/dolt/commands/reflog.go index 9c633394e7..3e49ed0ec2 100644 --- a/go/cmd/dolt/commands/reflog.go +++ b/go/cmd/dolt/commands/reflog.go @@ -107,12 +107,26 @@ func (cmd ReflogCmd) Exec(ctx context.Context, commandStr string, args []string, func constructInterpolatedDoltReflogQuery(apr *argparser.ArgParseResults) (string, error) { var params []interface{} refPlaceholder := "" + allFlag := "" + if apr.NArg() == 1 { params = append(params, apr.Arg(0)) refPlaceholder = "?" } + if apr.Contains(cli.AllFlag) { + allFlag = "'--all'" + } - query := strings.Join([]string{"SELECT ref, commit_hash, commit_message FROM DOLT_REFLOG(", refPlaceholder, ")"}, "") + args := "" + if refPlaceholder == "" && allFlag != "" { + args = allFlag + } else if refPlaceholder != "" && allFlag == "" { + args = refPlaceholder + } else if refPlaceholder != "" && allFlag != "" { + args = strings.Join([]string{refPlaceholder, allFlag}, ", ") + } + + query := strings.Join([]string{"SELECT ref, commit_hash, commit_message FROM DOLT_REFLOG(", args, ")"}, "") interpolatedQuery, err := dbr.InterpolateForDialect(query, params, dialect.MySQL) if err != nil { return "", err @@ -183,6 +197,8 @@ func processRefForReflog(fullRef string, curBranch string) string { return fmt.Sprintf("\033[33mtag: %s\033[0m", strings.TrimPrefix(fullRef, "refs/tags/")) // tag in yellow (33m) } else if strings.HasPrefix(fullRef, "refs/remotes/") { return fmt.Sprintf("\033[31;1m%s\033[0m", strings.TrimPrefix(fullRef, "refs/remotes/")) // remote in red (31;1m) + } else if strings.HasPrefix(fullRef, "refs/workspaces/") { + return fmt.Sprintf("\033[35;1mworkspace: %s\033[0m", strings.TrimPrefix(fullRef, "refs/workspaces/")) // workspace in magenta (35;1m) } else { return fullRef } diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index 64b23a4de4..9c6edfb9e1 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -20,6 +20,7 @@ import ( "strings" "time" + "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/types" @@ -31,7 +32,8 @@ import ( type ReflogTableFunction struct { ctx *sql.Context database sql.Database - refExpr sql.Expression + refName string + showAll bool } var _ sql.TableFunction = (*ReflogTableFunction)(nil) @@ -64,20 +66,6 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row return nil, fmt.Errorf("unexpected database type: %T", rltf.database) } - var refName string - if rltf.refExpr != nil { - target, err := rltf.refExpr.Eval(ctx, row) - if err != nil { - return nil, fmt.Errorf("error evaluating expression (%s): %s", - rltf.refExpr.String(), err.Error()) - } - - refName, ok = target.(string) - if !ok { - return nil, fmt.Errorf("argument (%v) is not a string value, but a %T", target, target) - } - } - ddb := sqlDb.DbData().Ddb journal := ddb.ChunkJournal() if journal == nil { @@ -109,17 +97,23 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row if doltRef.GetType() == ref.InternalRefType { return nil } + // skip workspace refs by default + if doltRef.GetType() == ref.WorkspaceRefType { + if !rltf.showAll { + return nil + } + } // If a ref expression to filter on was specified, see if we match the current ref - if rltf.refExpr != nil { + if rltf.refName != "" { // If the caller has supplied a branch or tag name, without the fully qualified ref path, // take the first match and use that as the canonical ref to filter on - if strings.HasSuffix(strings.ToLower(id), "/"+strings.ToLower(refName)) { - refName = id + if strings.HasSuffix(strings.ToLower(id), "/"+strings.ToLower(rltf.refName)) { + rltf.refName = id } // Skip refs that don't match the target we're looking for - if strings.ToLower(id) != strings.ToLower(refName) { + if strings.ToLower(id) != strings.ToLower(rltf.refName) { return nil } } @@ -172,14 +166,11 @@ func (rltf *ReflogTableFunction) Schema() sql.Schema { } func (rltf *ReflogTableFunction) Resolved() bool { - if rltf.refExpr != nil { - return rltf.refExpr.Resolved() - } return true } func (rltf *ReflogTableFunction) String() string { - return fmt.Sprintf("DOLT_REFLOG(%s)", rltf.refExpr.String()) + return fmt.Sprintf("DOLT_REFLOG(%s)", rltf.refName) } func (rltf *ReflogTableFunction) Children() []sql.Node { @@ -204,20 +195,25 @@ func (rltf *ReflogTableFunction) IsReadOnly() bool { } func (rltf *ReflogTableFunction) Expressions() []sql.Expression { - if rltf.refExpr != nil { - return []sql.Expression{rltf.refExpr} - } return []sql.Expression{} } func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) (sql.Node, error) { - if len(expression) > 1 { - return nil, sql.ErrInvalidArgumentNumber.New(rltf.Name(), "0 or 1", len(expression)) + if len(expression) > 2 { + return nil, sql.ErrInvalidArgumentNumber.New(rltf.Name(), "0 to 2", len(expression)) } new := *rltf - if len(expression) > 0 { - new.refExpr = expression[0] + args, err := getDoltArgs(rltf.ctx, expression, rltf.Name()) + if err != nil { + return nil, err + } + apr, err := cli.CreateReflogArgParser().Parse(args) + if apr.NArg() > 0 { + new.refName = apr.Arg(0) + } + if apr.Contains(cli.AllFlag) { + new.showAll = true } return &new, nil } From 37158e01a6b071d80c29e5699e35c6fa00276e8e Mon Sep 17 00:00:00 2001 From: stephkyou Date: Tue, 21 Nov 2023 21:04:50 +0000 Subject: [PATCH 04/17] [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh --- go/cmd/dolt/commands/reflog.go | 7 ++++--- go/libraries/doltcore/sqle/reflog_table_function.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/go/cmd/dolt/commands/reflog.go b/go/cmd/dolt/commands/reflog.go index 3e49ed0ec2..14aa3bc71b 100644 --- a/go/cmd/dolt/commands/reflog.go +++ b/go/cmd/dolt/commands/reflog.go @@ -19,15 +19,16 @@ import ( "fmt" "strings" + "github.com/dolthub/go-mysql-server/sql" + "github.com/gocraft/dbr/v2" + "github.com/gocraft/dbr/v2/dialect" + "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/dolt/go/cmd/dolt/errhand" eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1" "github.com/dolthub/dolt/go/libraries/doltcore/env" "github.com/dolthub/dolt/go/libraries/utils/argparser" "github.com/dolthub/dolt/go/store/util/outputpager" - "github.com/dolthub/go-mysql-server/sql" - "github.com/gocraft/dbr/v2" - "github.com/gocraft/dbr/v2/dialect" ) var reflogDocs = cli.CommandDocumentationContent{ diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index 9c6edfb9e1..63c563727f 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -20,10 +20,10 @@ import ( "strings" "time" - "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/types" + "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/dolt/go/libraries/doltcore/ref" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" "github.com/dolthub/dolt/go/store/hash" From 6ba1d09cd893d050a1ed826dd4c60e168d0bd179 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Tue, 21 Nov 2023 13:45:35 -0800 Subject: [PATCH 05/17] change error test output --- go/libraries/doltcore/sqle/enginetest/dolt_queries.go | 6 +++--- go/libraries/doltcore/sqle/reflog_table_function.go | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 91e97f461d..206c9318ed 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -4317,15 +4317,15 @@ var DoltReflogTestScripts = []queries.ScriptTest{ Assertions: []queries.ScriptTestAssertion{ { Query: "select * from dolt_reflog('foo', 'bar');", - ExpectedErrStr: "function 'dolt_reflog' expected 0 or 1 arguments, 2 received", + ExpectedErrStr: "error: reflog has too many positional arguments. Expected at most 1, found 2: foo, bar", }, { Query: "select * from dolt_reflog(NULL);", - ExpectedErrStr: "argument () is not a string value, but a ", + ExpectedErrStr: "Invalid argument to dolt_reflog: NULL", }, { Query: "select * from dolt_reflog(-100);", - ExpectedErrStr: "argument (-100) is not a string value, but a int8", + ExpectedErrStr: "Invalid argument to dolt_reflog: -100", }, }, }, diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index 63c563727f..a8eb79ed8e 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -209,6 +209,9 @@ func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) ( return nil, err } apr, err := cli.CreateReflogArgParser().Parse(args) + if err != nil { + return nil, err + } if apr.NArg() > 0 { new.refName = apr.Arg(0) } From 3e5c6b6bb7365a2d3168c6d14cd6081c49d03ef2 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Tue, 21 Nov 2023 14:20:08 -0800 Subject: [PATCH 06/17] minor test updates --- integration-tests/bats/helper/local-remote.bash | 2 ++ integration-tests/bats/reflog.bats | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/integration-tests/bats/helper/local-remote.bash b/integration-tests/bats/helper/local-remote.bash index f478ffa6b9..e799355407 100644 --- a/integration-tests/bats/helper/local-remote.bash +++ b/integration-tests/bats/helper/local-remote.bash @@ -135,6 +135,8 @@ SKIP_SERVER_TESTS=$(cat <<-EOM ~cli-hosted.bats~ ~profile.bats~ ~ls.bats~ +~reflog.bats~ +~sql-reflog.bats~ EOM ) diff --git a/integration-tests/bats/reflog.bats b/integration-tests/bats/reflog.bats index d8906f4794..bad3273d50 100755 --- a/integration-tests/bats/reflog.bats +++ b/integration-tests/bats/reflog.bats @@ -217,7 +217,7 @@ SQL @test "reflog: too many arguments given" { run dolt reflog foo bar [ "$status" -eq 1 ] - [[ "$output" =~ "error: reflog has too many positional arguments" ]] + [[ "$output" =~ "error: reflog has too many positional arguments" ]] || false } @test "reflog: unknown ref returns nothing" { From 5d24edd9eff559bfde9227d729547a3f8c1ad682 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Wed, 29 Nov 2023 18:43:36 -0800 Subject: [PATCH 07/17] address PR comments --- go/cmd/dolt/commands/reflog.go | 31 +++--- .../doltcore/sqle/enginetest/dolt_queries.go | 6 +- .../doltcore/sqle/reflog_table_function.go | 67 +++++++++---- .../bats/helper/local-remote.bash | 1 - integration-tests/bats/reflog.bats | 96 +++++++++++-------- integration-tests/bats/sql-local-remote.bats | 24 +++++ integration-tests/bats/sql-reflog.bats | 10 +- 7 files changed, 146 insertions(+), 89 deletions(-) diff --git a/go/cmd/dolt/commands/reflog.go b/go/cmd/dolt/commands/reflog.go index 14aa3bc71b..bc1b85c685 100644 --- a/go/cmd/dolt/commands/reflog.go +++ b/go/cmd/dolt/commands/reflog.go @@ -107,27 +107,17 @@ func (cmd ReflogCmd) Exec(ctx context.Context, commandStr string, args []string, // Also interpolates this query to prevent sql injection func constructInterpolatedDoltReflogQuery(apr *argparser.ArgParseResults) (string, error) { var params []interface{} - refPlaceholder := "" - allFlag := "" + var args []string if apr.NArg() == 1 { params = append(params, apr.Arg(0)) - refPlaceholder = "?" + args = append(args, "?") } if apr.Contains(cli.AllFlag) { - allFlag = "'--all'" + args = append(args, "'--all'") } - args := "" - if refPlaceholder == "" && allFlag != "" { - args = allFlag - } else if refPlaceholder != "" && allFlag == "" { - args = refPlaceholder - } else if refPlaceholder != "" && allFlag != "" { - args = strings.Join([]string{refPlaceholder, allFlag}, ", ") - } - - query := strings.Join([]string{"SELECT ref, commit_hash, commit_message FROM DOLT_REFLOG(", args, ")"}, "") + query := fmt.Sprintf("SELECT ref, commit_hash, commit_message FROM DOLT_REFLOG(%s)", strings.Join(args, ", ")) interpolatedQuery, err := dbr.InterpolateForDialect(query, params, dialect.MySQL) if err != nil { return "", err @@ -147,11 +137,12 @@ func printReflog(rows []sql.Row, queryist cli.Queryist, sqlCtx *sql.Context) int var reflogInfo []ReflogInfo // Get the current branch + curBranch := "" res, err := GetRowsForSql(queryist, sqlCtx, "SELECT active_branch()") - if err != nil { - return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), nil) + if err == nil { + // still print the reflog even if we can't get the current branch + curBranch = res[0][0].(string) } - curBranch := res[0][0].(string) for _, row := range rows { ref := row[0].(string) @@ -174,13 +165,13 @@ func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) { pager := outputpager.Start() defer pager.Stop() - for pos, info := range reflogInfo { + for _, info := range reflogInfo { // TODO: use short hash instead line := []string{fmt.Sprintf("\033[33m%s\033[0m", info.commitHash)} // commit hash in yellow (33m) processedRef := processRefForReflog(info.ref, curBranch) line = append(line, fmt.Sprintf("\033[33m(%s\033[33m)\033[0m", processedRef)) // () in yellow (33m) - line = append(line, fmt.Sprintf("HEAD@{%d}: %s\n", pos, info.commitMessage)) + line = append(line, fmt.Sprintf("%s\n", info.commitMessage)) pager.Writer.Write([]byte(strings.Join(line, " "))) } }) @@ -190,7 +181,7 @@ func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) { func processRefForReflog(fullRef string, curBranch string) string { if strings.HasPrefix(fullRef, "refs/heads/") { branch := strings.TrimPrefix(fullRef, "refs/heads/") - if branch == curBranch { + if curBranch != "" && branch == curBranch { return fmt.Sprintf("\033[36;1mHEAD -> \033[32;1m%s\033[0m", branch) // HEAD in cyan (36;1), branch in green (32;1m) } return fmt.Sprintf("\033[32;1m%s\033[0m", branch) // branch in green (32;1m) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 206c9318ed..57e1d2ca70 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -4317,15 +4317,15 @@ var DoltReflogTestScripts = []queries.ScriptTest{ Assertions: []queries.ScriptTestAssertion{ { Query: "select * from dolt_reflog('foo', 'bar');", - ExpectedErrStr: "error: reflog has too many positional arguments. Expected at most 1, found 2: foo, bar", + ExpectedErrStr: "error: dolt_reflog has too many positional arguments. Expected at most 1, found 2: ['foo' 'bar']", }, { Query: "select * from dolt_reflog(NULL);", - ExpectedErrStr: "Invalid argument to dolt_reflog: NULL", + ExpectedErrStr: "argument () is not a string value, but a ", }, { Query: "select * from dolt_reflog(-100);", - ExpectedErrStr: "Invalid argument to dolt_reflog: -100", + ExpectedErrStr: "argument (-100) is not a string value, but a int8", }, }, }, diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index a8eb79ed8e..f0124a84bf 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -23,7 +23,6 @@ import ( "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/types" - "github.com/dolthub/dolt/go/cmd/dolt/cli" "github.com/dolthub/dolt/go/libraries/doltcore/ref" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" "github.com/dolthub/dolt/go/store/hash" @@ -32,7 +31,7 @@ import ( type ReflogTableFunction struct { ctx *sql.Context database sql.Database - refName string + refExpr sql.Expression showAll bool } @@ -66,6 +65,20 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row return nil, fmt.Errorf("unexpected database type: %T", rltf.database) } + var refName string + if rltf.refExpr != nil { + target, err := rltf.refExpr.Eval(ctx, row) + if err != nil { + return nil, fmt.Errorf("error evaluating expression (%s): %s", + rltf.refExpr.String(), err.Error()) + } + + refName, ok = target.(string) + if !ok { + return nil, fmt.Errorf("argument (%v) is not a string value, but a %T", target, target) + } + } + ddb := sqlDb.DbData().Ddb journal := ddb.ChunkJournal() if journal == nil { @@ -105,15 +118,15 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row } // If a ref expression to filter on was specified, see if we match the current ref - if rltf.refName != "" { + if refName != "" { // If the caller has supplied a branch or tag name, without the fully qualified ref path, // take the first match and use that as the canonical ref to filter on - if strings.HasSuffix(strings.ToLower(id), "/"+strings.ToLower(rltf.refName)) { - rltf.refName = id + if strings.HasSuffix(strings.ToLower(id), "/"+strings.ToLower(refName)) { + refName = id } // Skip refs that don't match the target we're looking for - if strings.ToLower(id) != strings.ToLower(rltf.refName) { + if strings.ToLower(id) != strings.ToLower(refName) { return nil } } @@ -166,11 +179,21 @@ func (rltf *ReflogTableFunction) Schema() sql.Schema { } func (rltf *ReflogTableFunction) Resolved() bool { + if rltf.refExpr != nil { + return rltf.refExpr.Resolved() + } return true } func (rltf *ReflogTableFunction) String() string { - return fmt.Sprintf("DOLT_REFLOG(%s)", rltf.refName) + var args []string + if rltf.showAll { + args = append(args, "'--all'") + } + if rltf.refExpr != nil { + args = append(args, rltf.refExpr.String()) + } + return fmt.Sprintf("DOLT_REFLOG(%s)", strings.Join(args, ", ")) } func (rltf *ReflogTableFunction) Children() []sql.Node { @@ -195,6 +218,9 @@ func (rltf *ReflogTableFunction) IsReadOnly() bool { } func (rltf *ReflogTableFunction) Expressions() []sql.Expression { + if rltf.refExpr != nil { + return []sql.Expression{rltf.refExpr} + } return []sql.Expression{} } @@ -204,20 +230,23 @@ func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) ( } new := *rltf - args, err := getDoltArgs(rltf.ctx, expression, rltf.Name()) - if err != nil { - return nil, err + + if len(expression) == 2 { + if expression[0].String() == "'--all'" && expression[1].String() == "'--all'" { + return nil, fmt.Errorf("error: multiple values provided for `all`") + } + if expression[0].String() != "'--all'" && expression[1].String() != "'--all'" { + return nil, fmt.Errorf("error: %s has too many positional arguments. Expected at most %d, found %d: %s", rltf.Name(), 1, 2, expression) + } } - apr, err := cli.CreateReflogArgParser().Parse(args) - if err != nil { - return nil, err - } - if apr.NArg() > 0 { - new.refName = apr.Arg(0) - } - if apr.Contains(cli.AllFlag) { - new.showAll = true + for _, expr := range expression { + if expr.String() != "'--all'" { + new.refExpr = expr + } else { + new.showAll = true + } } + return &new, nil } diff --git a/integration-tests/bats/helper/local-remote.bash b/integration-tests/bats/helper/local-remote.bash index e799355407..5b2ad0e664 100644 --- a/integration-tests/bats/helper/local-remote.bash +++ b/integration-tests/bats/helper/local-remote.bash @@ -136,7 +136,6 @@ SKIP_SERVER_TESTS=$(cat <<-EOM ~profile.bats~ ~ls.bats~ ~reflog.bats~ -~sql-reflog.bats~ EOM ) diff --git a/integration-tests/bats/reflog.bats b/integration-tests/bats/reflog.bats index bad3273d50..93d54fda02 100755 --- a/integration-tests/bats/reflog.bats +++ b/integration-tests/bats/reflog.bats @@ -1,10 +1,6 @@ #!/usr/bin/env bats load $BATS_TEST_DIRNAME/helper/common.bash -setup() { - setup_common -} - teardown() { assert_feature_version teardown_common @@ -13,6 +9,8 @@ teardown() { # Asserts that when DOLT_DISABLE_REFLOG is set, dolt reflog returns nothing with no error. @test "reflog: disabled with DOLT_DISABLE_REFLOG" { export DOLT_DISABLE_REFLOG=true + setup_common # need to set env vars before setup_common for remote tests + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" @@ -27,6 +25,8 @@ teardown() { # most recent entries and is limited by the env var's value. @test "reflog: set DOLT_REFLOG_RECORD_LIMIT" { export DOLT_REFLOG_RECORD_LIMIT=2 + setup_common # need to set env vars before setup_common for remote tests + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" @@ -43,6 +43,8 @@ teardown() { } @test "reflog: simple reflog" { + setup_common + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" @@ -51,11 +53,13 @@ teardown() { [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(HEAD -> main) HEAD@{0}: initial commit" ]] || false - [[ "$out" =~ "HEAD@{1}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) initial commit" ]] || false + [[ "$out" =~ "Initialize data repository" ]] || false } @test "reflog: reflog with ref given" { + setup_common + dolt sql < main) HEAD@{0}: inserting row 1" ]] || false - [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false - [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) inserting row 1" ]] || false + [[ "$out" =~ "creating table t1" ]] || false + [[ "$out" =~ "Initialize data repository" ]] || false # ref is case-insensitive run dolt reflog rEFs/heAdS/MAIN [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(HEAD -> main) HEAD@{0}: inserting row 1" ]] || false - [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false - [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) inserting row 1" ]] || false + [[ "$out" =~ "creating table t1" ]] || false + [[ "$out" =~ "Initialize data repository" ]] || false run dolt reflog main [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(HEAD -> main) HEAD@{0}: inserting row 1" ]] || false - [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false - [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) inserting row 1" ]] || false + [[ "$out" =~ "creating table t1" ]] || false + [[ "$out" =~ "Initialize data repository" ]] || false # ref is case-insensitive run dolt reflog MaIn [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(HEAD -> main) HEAD@{0}: inserting row 1" ]] || false - [[ "$out" =~ "HEAD@{1}: creating table t1" ]] || false - [[ "$out" =~ "HEAD@{2}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) inserting row 1" ]] || false + [[ "$out" =~ "creating table t1" ]] || false + [[ "$out" =~ "Initialize data repository" ]] || false run dolt reflog refs/heads/branch1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(branch1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 2" ]] || false - [[ "$out" =~ "HEAD@{2}: inserting row 1" ]] || false + [[ "$out" =~ "(branch1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 2" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false run dolt reflog branch1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(branch1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 2" ]] || false - [[ "$out" =~ "HEAD@{2}: inserting row 1" ]] || false + [[ "$out" =~ "(branch1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 2" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false run dolt reflog refs/tags/tag1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + [[ "$out" =~ "(tag: tag1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false # ref is case-insensitive run dolt reflog Refs/tAGs/TaG1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + [[ "$out" =~ "(tag: tag1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false run dolt reflog tag1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + [[ "$out" =~ "(tag: tag1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false # ref is case-insensitive run dolt reflog TAg1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + [[ "$out" =~ "(tag: tag1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false dolt branch -D branch1 @@ -160,25 +164,27 @@ SQL [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(branch1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 2" ]] || false - [[ "$out" =~ "HEAD@{2}: inserting row 1" ]] || false + [[ "$out" =~ "(branch1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 2" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false dolt tag -d tag1 run dolt reflog tag1 [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(tag: tag1) HEAD@{0}: inserting row 3" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false + [[ "$out" =~ "(tag: tag1) inserting row 3" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false } @test "reflog: garbage collection with no newgen data" { + setup_common + run dolt reflog [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 1 ] out=$(echo "$output" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color - [[ "$out" =~ "(HEAD -> main) HEAD@{0}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) Initialize data repository" ]] || false dolt gc @@ -188,6 +194,8 @@ SQL } @test "reflog: garbage collection with newgen data" { + setup_common + dolt sql < main) HEAD@{0}: inserting row 2" ]] || false - [[ "$out" =~ "HEAD@{1}: inserting row 1" ]] || false - [[ "$out" =~ "HEAD@{2}: creating table t1" ]] || false - [[ "$out" =~ "HEAD@{3}: Initialize data repository" ]] || false + [[ "$out" =~ "(HEAD -> main) inserting row 2" ]] || false + [[ "$out" =~ "inserting row 1" ]] || false + [[ "$out" =~ "creating table t1" ]] || false + [[ "$out" =~ "Initialize data repository" ]] || false dolt gc @@ -215,12 +223,16 @@ SQL } @test "reflog: too many arguments given" { + setup_common + run dolt reflog foo bar [ "$status" -eq 1 ] [[ "$output" =~ "error: reflog has too many positional arguments" ]] || false } @test "reflog: unknown ref returns nothing" { + setup_common + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" diff --git a/integration-tests/bats/sql-local-remote.bats b/integration-tests/bats/sql-local-remote.bats index 95366a0239..4190124668 100644 --- a/integration-tests/bats/sql-local-remote.bats +++ b/integration-tests/bats/sql-local-remote.bats @@ -1270,3 +1270,27 @@ SQL [[ "$localOutput" == "$remoteOutput" ]] || false } + +@test "sql-local-remote: verify dolt reflog behavior" { + cd altDB + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + + run dolt --verbose-engine-setup reflog + [ $status -eq 0 ] + [[ "$output" =~ "starting local mode" ]] || false + [[ "$output" =~ "initial commit" ]] || false + run dolt reflog + localOutput=$output + + start_sql_server altDB + run dolt --verbose-engine-setup reflog + [ $status -eq 0 ] + [[ "$output" =~ "starting remote mode" ]] || false + [[ "$output" =~ "initial commit" ]] || false + run dolt reflog + remoteOutput=$output + + [[ "$localOutput" == "$remoteOutput" ]] || false +} diff --git a/integration-tests/bats/sql-reflog.bats b/integration-tests/bats/sql-reflog.bats index bac628f016..6e52d0a3e1 100644 --- a/integration-tests/bats/sql-reflog.bats +++ b/integration-tests/bats/sql-reflog.bats @@ -1,10 +1,6 @@ #!/usr/bin/env bats load $BATS_TEST_DIRNAME/helper/common.bash -setup() { - setup_common -} - teardown() { assert_feature_version teardown_common @@ -14,6 +10,8 @@ teardown() { # function returns an empty result set with no error. @test "sql-reflog: disabled with DOLT_DISABLE_REFLOG" { export DOLT_DISABLE_REFLOG=true + setup_common # need to set env vars before setup_common for remote tests + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" @@ -26,6 +24,8 @@ teardown() { # Sanity check for the most basic case of querying the Dolt reflog @test "sql-reflog: enabled by default" { + setup_common + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" @@ -41,6 +41,8 @@ teardown() { # most recent entries and is limited by the env var's value. @test "sql-reflog: set DOLT_REFLOG_RECORD_LIMIT" { export DOLT_REFLOG_RECORD_LIMIT=2 + setup_common # need to set env vars before setup_common for remote tests + dolt sql -q "create table t (i int primary key, j int);" dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; dolt commit -Am "initial commit" From 0f2e9261e351b94de397749070efb3a1be9db974 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Thu, 30 Nov 2023 11:28:52 -0800 Subject: [PATCH 08/17] reflog doc update --- go/cmd/dolt/commands/reflog.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/dolt/commands/reflog.go b/go/cmd/dolt/commands/reflog.go index bc1b85c685..0653aba3fd 100644 --- a/go/cmd/dolt/commands/reflog.go +++ b/go/cmd/dolt/commands/reflog.go @@ -42,7 +42,7 @@ Dolt's reflog is similar to [Git's reflog](https://git-scm.com/docs/git-reflog), - The Dolt reflog currently only supports named references, such as branches and tags, and not any of Git's special refs (e.g. {{.EmphasisLeft}}HEAD{{.EmphasisRight}}, {{.EmphasisLeft}}FETCH-HEAD{{.EmphasisRight}}, {{.EmphasisLeft}}MERGE-HEAD{{.EmphasisRight}}). - The Dolt reflog can be queried for the log of references, even after a reference has been deleted. In Git, once a branch or tag is deleted, the reflog for that ref is also deleted and to find the last commit a branch or tag pointed to you have to use Git's special {{.EmphasisLeft}}HEAD{{.EmphasisRight}} reflog to find the commit, which can sometimes be challenging. Dolt makes this much easier by allowing you to see the history for a deleted ref so you can easily see the last commit a branch or tag pointed to before it was deleted.`, Synopsis: []string{ - `{{.LessThan}}ref{{.GreaterThan}}`, + `[--all] {{.LessThan}}ref{{.GreaterThan}}`, }, } From e9c63acccd7e13a9c30b7b462bd7c31671445cf9 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Thu, 30 Nov 2023 11:37:12 -0800 Subject: [PATCH 09/17] another description update --- go/cmd/dolt/cli/arg_parser_helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/dolt/cli/arg_parser_helpers.go b/go/cmd/dolt/cli/arg_parser_helpers.go index 83e87cbfe3..4693ba02ff 100644 --- a/go/cmd/dolt/cli/arg_parser_helpers.go +++ b/go/cmd/dolt/cli/arg_parser_helpers.go @@ -282,7 +282,7 @@ func CreateCountCommitsArgParser() *argparser.ArgParser { func CreateReflogArgParser() *argparser.ArgParser { ap := argparser.NewArgParserWithMaxArgs("reflog", 1) - ap.SupportsFlag(AllFlag, "", "Show all refs") + ap.SupportsFlag(AllFlag, "", "Show all refs, including hidden refs, such as DoltHub workspace refs") return ap } From 5cfc7e482d63db9b9e5714af05ea028ba524fdd2 Mon Sep 17 00:00:00 2001 From: Aaron Son Date: Thu, 30 Nov 2023 14:58:05 -0800 Subject: [PATCH 10/17] [no-release-notes] go/libraries/doltcore/remotestorage: Fix some spurious retries on authentication failures and the likes when interacting with remotestorage. --- .../doltcore/remotesrv/interceptors.go | 6 ++---- .../doltcore/remotestorage/chunk_store.go | 6 ++++-- go/libraries/doltcore/remotestorage/error.go | 4 ++++ go/libraries/doltcore/remotestorage/retry.go | 19 ++++++++++++------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/go/libraries/doltcore/remotesrv/interceptors.go b/go/libraries/doltcore/remotesrv/interceptors.go index 0937726997..79c42abc00 100644 --- a/go/libraries/doltcore/remotesrv/interceptors.go +++ b/go/libraries/doltcore/remotesrv/interceptors.go @@ -79,15 +79,13 @@ func (si *ServerInterceptor) authenticate(ctx context.Context) error { ctx, err := si.AccessController.ApiAuthenticate(ctx) if err != nil { si.Lgr.Warnf("authentication failed: %s", err.Error()) - status.Error(codes.Unauthenticated, "unauthenticated") - return err + return status.Error(codes.Unauthenticated, err.Error()) } // Have a valid user in the context. Check authorization. if authorized, err := si.AccessController.ApiAuthorize(ctx); !authorized { si.Lgr.Warnf("authorization failed: %s", err.Error()) - status.Error(codes.PermissionDenied, "unauthorized") - return err + return status.Error(codes.PermissionDenied, err.Error()) } // Access Granted. diff --git a/go/libraries/doltcore/remotestorage/chunk_store.go b/go/libraries/doltcore/remotestorage/chunk_store.go index 72250f3c22..522e25e621 100644 --- a/go/libraries/doltcore/remotestorage/chunk_store.go +++ b/go/libraries/doltcore/remotestorage/chunk_store.go @@ -1011,9 +1011,11 @@ func (dcs *DoltChunkStore) uploadTableFileWithRetries(ctx context.Context, table req := &remotesapi.GetUploadLocsRequest{RepoId: id, RepoToken: token, RepoPath: dcs.repoPath, TableFileDetails: []*remotesapi.TableFileDetails{tbfd}} resp, err := dcs.csClient.GetUploadLocations(ctx, req) if err != nil { - if err != nil { - return NewRpcError(err, "GetUploadLocations", dcs.host, req) + err := NewRpcError(err, "GetUploadLocations", dcs.host, req) + if err.IsPermanent() { + return backoff.Permanent(err) } + return err } if resp.RepoToken != "" { diff --git a/go/libraries/doltcore/remotestorage/error.go b/go/libraries/doltcore/remotestorage/error.go index 005ee78f92..f83a446bea 100644 --- a/go/libraries/doltcore/remotestorage/error.go +++ b/go/libraries/doltcore/remotestorage/error.go @@ -38,6 +38,10 @@ func (rpce *RpcError) Error() string { return rpce.originalErrMsg } +func (rpce *RpcError) IsPermanent() bool { + return statusCodeIsPermanentError(rpce.status) +} + func (rpce *RpcError) FullDetails() string { jsonStr, _ := GetJsonEncodedRequest(rpce) return rpce.originalErrMsg + "\nhost:" + rpce.host + "\nrpc: " + rpce.rpc + "\nparams:" + jsonStr diff --git a/go/libraries/doltcore/remotestorage/retry.go b/go/libraries/doltcore/remotestorage/retry.go index 80b1d4bd08..6c1b71101c 100644 --- a/go/libraries/doltcore/remotestorage/retry.go +++ b/go/libraries/doltcore/remotestorage/retry.go @@ -46,12 +46,18 @@ func processHttpResp(resp *http.Response, err error) error { // ProcessGrpcErr converts an error from a Grpc call into a RetriableCallState func processGrpcErr(err error) error { - st, ok := status.FromError(err) - if !ok { - return err + st, _ := status.FromError(err) + if statusCodeIsPermanentError(st) { + return backoff.Permanent(err) } + return err +} - switch st.Code() { +func statusCodeIsPermanentError(s *status.Status) bool { + if s == nil { + return false + } + switch s.Code() { case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, @@ -60,8 +66,7 @@ func processGrpcErr(err error) error { codes.Unimplemented, codes.OutOfRange, codes.Unauthenticated: - return backoff.Permanent(err) + return true } - - return err + return false } From 83602c2f80ee4c05251702a46621b7450db2a0cf Mon Sep 17 00:00:00 2001 From: Aaron Son Date: Thu, 30 Nov 2023 16:23:37 -0800 Subject: [PATCH 11/17] [no-release-notes] integration-tests/bats: ls.bats: Fix a flakey failure where an unlucky hash could cause a negative assertion to fail. ls.bats was using test table names like `t1` and `t2` and making assertions against the output of `dolt ls`. But the output of `dolt ls` also sometimes includes a commit hash, which can itself contain these strings. Change it so that we use names which will never appear in a commit hash. --- integration-tests/bats/ls.bats | 126 ++++++++++++++++----------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/integration-tests/bats/ls.bats b/integration-tests/bats/ls.bats index e3437440af..498bff7cc6 100755 --- a/integration-tests/bats/ls.bats +++ b/integration-tests/bats/ls.bats @@ -3,10 +3,10 @@ load $BATS_TEST_DIRNAME/helper/common.bash setup() { setup_common - dolt sql -q "create table t1 (pk int PRIMARY KEY)" - dolt commit -Am "create table t1" - dolt sql -q "create table t2 (pk int PRIMARY KEY)" - dolt commit -Am "create table t2" + dolt sql -q "create table table_one (pk int PRIMARY KEY)" + dolt commit -Am "create table table_one" + dolt sql -q "create table table_two (pk int PRIMARY KEY)" + dolt commit -Am "create table table_two" } teardown() { @@ -18,42 +18,42 @@ teardown() { [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] [[ "$output" =~ "Tables in working set:" ]] || false - [[ "$output" =~ "t1" ]] || false - [[ "$output" =~ "t2" ]] || false + [[ "$output" =~ "table_one" ]] || false + [[ "$output" =~ "table_two" ]] || false } @test "ls: ls includes unstaged table" { - dolt sql -q "create table t3 (pk int PRIMARY KEY)" + dolt sql -q "create table table_three (pk int PRIMARY KEY)" run dolt ls [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 4 ] [[ "$output" =~ "Tables in working set:" ]] || false - [[ "$output" =~ "t1" ]] || false - [[ "$output" =~ "t2" ]] || false - [[ "$output" =~ "t3" ]] || false + [[ "$output" =~ "table_one" ]] || false + [[ "$output" =~ "table_two" ]] || false + [[ "$output" =~ "table_three" ]] || false } @test "ls: ls includes staged table" { - dolt sql -q "create table t3 (pk int PRIMARY KEY)" + dolt sql -q "create table table_three (pk int PRIMARY KEY)" dolt add . run dolt ls [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 4 ] [[ "$output" =~ "Tables in working set:" ]] || false - [[ "$output" =~ "t1" ]] || false - [[ "$output" =~ "t2" ]] || false - [[ "$output" =~ "t3" ]] || false + [[ "$output" =~ "table_one" ]] || false + [[ "$output" =~ "table_two" ]] || false + [[ "$output" =~ "table_three" ]] || false } @test "ls: --verbose shows row count" { - dolt sql -q "insert into t1 values (1), (2), (3)" + dolt sql -q "insert into table_one values (1), (2), (3)" run dolt ls --verbose [ "$status" -eq 0 ] [[ "$output" =~ "Tables in working set:" ]] || false - [[ "$output" =~ "t1" ]] || false + [[ "$output" =~ "table_one" ]] || false [[ "$output" =~ "3 rows" ]] || false - [[ "$output" =~ "t2" ]] || false + [[ "$output" =~ "table_two" ]] || false [[ "$output" =~ "0 rows" ]] || false } @@ -71,24 +71,24 @@ teardown() { [[ "$output" =~ "dolt_remotes" ]] || false [[ "$output" =~ "dolt_branches" ]] || false [[ "$output" =~ "dolt_remote_branches" ]] || false - [[ "$output" =~ "dolt_constraint_violations_t1" ]] || false - [[ "$output" =~ "dolt_history_t1" ]] || false - [[ "$output" =~ "dolt_conflicts_t1" ]] || false - [[ "$output" =~ "dolt_diff_t1" ]] || false - [[ "$output" =~ "dolt_commit_diff_t1" ]] || false - [[ "$output" =~ "dolt_constraint_violations_t2" ]] || false - [[ "$output" =~ "dolt_history_t2" ]] || false - [[ "$output" =~ "dolt_conflicts_t2" ]] || false - [[ "$output" =~ "dolt_diff_t2" ]] || false - [[ "$output" =~ "dolt_commit_diff_t2" ]] || false + [[ "$output" =~ "dolt_constraint_violations_table_one" ]] || false + [[ "$output" =~ "dolt_history_table_one" ]] || false + [[ "$output" =~ "dolt_conflicts_table_one" ]] || false + [[ "$output" =~ "dolt_diff_table_one" ]] || false + [[ "$output" =~ "dolt_commit_diff_table_one" ]] || false + [[ "$output" =~ "dolt_constraint_violations_table_two" ]] || false + [[ "$output" =~ "dolt_history_table_two" ]] || false + [[ "$output" =~ "dolt_conflicts_table_two" ]] || false + [[ "$output" =~ "dolt_diff_table_two" ]] || false + [[ "$output" =~ "dolt_commit_diff_table_two" ]] || false } @test "ls: --all shows tables in working set and system tables" { run dolt ls --all [ "$status" -eq 0 ] [[ "$output" =~ "Tables in working set:" ]] || false - [[ "$output" =~ "t1" ]] || false - [[ "$output" =~ "t2" ]] || false + [[ "$output" =~ "table_one" ]] || false + [[ "$output" =~ "table_two" ]] || false [[ "$output" =~ "System tables:" ]] || false [[ "$output" =~ "dolt_status" ]] || false [[ "$output" =~ "dolt_commits" ]] || false @@ -99,27 +99,27 @@ teardown() { [[ "$output" =~ "dolt_remotes" ]] || false [[ "$output" =~ "dolt_branches" ]] || false [[ "$output" =~ "dolt_remote_branches" ]] || false - [[ "$output" =~ "dolt_constraint_violations_t1" ]] || false - [[ "$output" =~ "dolt_history_t1" ]] || false - [[ "$output" =~ "dolt_conflicts_t1" ]] || false - [[ "$output" =~ "dolt_diff_t1" ]] || false - [[ "$output" =~ "dolt_commit_diff_t1" ]] || false - [[ "$output" =~ "dolt_constraint_violations_t2" ]] || false - [[ "$output" =~ "dolt_history_t2" ]] || false - [[ "$output" =~ "dolt_conflicts_t2" ]] || false - [[ "$output" =~ "dolt_diff_t2" ]] || false - [[ "$output" =~ "dolt_commit_diff_t2" ]] || false + [[ "$output" =~ "dolt_constraint_violations_table_one" ]] || false + [[ "$output" =~ "dolt_history_table_one" ]] || false + [[ "$output" =~ "dolt_conflicts_table_one" ]] || false + [[ "$output" =~ "dolt_diff_table_one" ]] || false + [[ "$output" =~ "dolt_commit_diff_table_one" ]] || false + [[ "$output" =~ "dolt_constraint_violations_table_two" ]] || false + [[ "$output" =~ "dolt_history_table_two" ]] || false + [[ "$output" =~ "dolt_conflicts_table_two" ]] || false + [[ "$output" =~ "dolt_diff_table_two" ]] || false + [[ "$output" =~ "dolt_commit_diff_table_two" ]] || false } @test "ls: --all and --verbose shows row count for tables in working set" { - dolt sql -q "insert into t1 values (1), (2), (3)" + dolt sql -q "insert into table_one values (1), (2), (3)" run dolt ls --all --verbose [ "$status" -eq 0 ] [[ "$output" =~ "Tables in working set:" ]] || false - [[ "$output" =~ "t1" ]] || false + [[ "$output" =~ "table_one" ]] || false [[ "$output" =~ "3 rows" ]] || false - [[ "$output" =~ "t2" ]] || false + [[ "$output" =~ "table_two" ]] || false [[ "$output" =~ "0 rows" ]] || false [[ "$output" =~ "System tables:" ]] || false [[ "$output" =~ "dolt_status" ]] || false @@ -131,16 +131,16 @@ teardown() { [[ "$output" =~ "dolt_remotes" ]] || false [[ "$output" =~ "dolt_branches" ]] || false [[ "$output" =~ "dolt_remote_branches" ]] || false - [[ "$output" =~ "dolt_constraint_violations_t1" ]] || false - [[ "$output" =~ "dolt_history_t1" ]] || false - [[ "$output" =~ "dolt_conflicts_t1" ]] || false - [[ "$output" =~ "dolt_diff_t1" ]] || false - [[ "$output" =~ "dolt_commit_diff_t1" ]] || false - [[ "$output" =~ "dolt_constraint_violations_t2" ]] || false - [[ "$output" =~ "dolt_history_t2" ]] || false - [[ "$output" =~ "dolt_conflicts_t2" ]] || false - [[ "$output" =~ "dolt_diff_t2" ]] || false - [[ "$output" =~ "dolt_commit_diff_t2" ]] || false + [[ "$output" =~ "dolt_constraint_violations_table_one" ]] || false + [[ "$output" =~ "dolt_history_table_one" ]] || false + [[ "$output" =~ "dolt_conflicts_table_one" ]] || false + [[ "$output" =~ "dolt_diff_table_one" ]] || false + [[ "$output" =~ "dolt_commit_diff_table_one" ]] || false + [[ "$output" =~ "dolt_constraint_violations_table_two" ]] || false + [[ "$output" =~ "dolt_history_table_two" ]] || false + [[ "$output" =~ "dolt_conflicts_table_two" ]] || false + [[ "$output" =~ "dolt_diff_table_two" ]] || false + [[ "$output" =~ "dolt_commit_diff_table_two" ]] || false } @test "ls: --system and --all are mutually exclusive" { @@ -153,33 +153,33 @@ teardown() { run dolt ls HEAD [ "$status" -eq 0 ] [[ "$output" =~ "Tables in " ]] || false # Tables in [hash]: - [[ "$output" =~ "t1" ]] || false - [[ "$output" =~ "t2" ]] || false + [[ "$output" =~ "table_one" ]] || false + [[ "$output" =~ "table_two" ]] || false run dolt ls HEAD~1 [ "$status" -eq 0 ] [[ "$output" =~ "Tables in " ]] || false # Tables in [hash]: - [[ "$output" =~ "t1" ]] || false - ! [[ "$output" =~ "t2" ]] || false + [[ "$output" =~ "table_one" ]] || false + ! [[ "$output" =~ "table_two" ]] || false } @test "ls: ls with branch" { dolt checkout -b branch1 - dolt sql -q "create table t3 (pk int primary key)" - dolt commit -Am "create table t3" + dolt sql -q "create table table_three (pk int primary key)" + dolt commit -Am "create table table_three" dolt checkout main run dolt ls branch1 [ "$status" -eq 0 ] [[ "$output" =~ "Tables in " ]] || false # Tables in [hash]: - [[ "$output" =~ "t1" ]] || false - [[ "$output" =~ "t2" ]] || false - [[ "$output" =~ "t3" ]] || false + [[ "$output" =~ "table_one" ]] || false + [[ "$output" =~ "table_two" ]] || false + [[ "$output" =~ "table_three" ]] || false } @test "ls: no tables in working set" { - dolt sql -q "drop table t1" - dolt sql -q "drop table t2" + dolt sql -q "drop table table_one" + dolt sql -q "drop table table_two" run dolt ls [ "$status" -eq 0 ] From a0c0fa6e5110be11934712911e302c2bcaa920b3 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Fri, 1 Dec 2023 11:10:55 -0800 Subject: [PATCH 12/17] Fix existant typo --- go/libraries/doltcore/doltdb/gc_test.go | 4 ++-- go/libraries/utils/set/strset_test.go | 2 +- go/store/types/apply_map_edits.go | 2 +- integration-tests/bats/1pk5col-ints.bats | 2 +- integration-tests/bats/conflict-detection.bats | 2 +- integration-tests/bats/create-views.bats | 2 +- integration-tests/bats/empty-repo.bats | 2 +- integration-tests/bats/import-create-tables.bats | 4 ++-- integration-tests/bats/remotes-aws.bats | 4 ++-- .../go-sql-server-driver/tests/sql-server-tls.yaml | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/go/libraries/doltcore/doltdb/gc_test.go b/go/libraries/doltcore/doltdb/gc_test.go index 1a99accd74..f99b30d0a7 100644 --- a/go/libraries/doltcore/doltdb/gc_test.go +++ b/go/libraries/doltcore/doltdb/gc_test.go @@ -154,10 +154,10 @@ func testGarbageCollection(t *testing.T, test gcTest) { // In September 2023, we found a failure to handle the `hasCache` in // `*NomsBlockStore` appropriately while cleaning up a memtable into which // dangling references had been written could result in writing chunks to a -// database which referenced non-existant chunks. +// database which referenced non-existent chunks. // // The general pattern was to get new chunk addresses into the hasCache, but -// not written to the store, and then to have an incoming chunk add a refenece +// not written to the store, and then to have an incoming chunk add a reference // to missing chunk. At that time, we would clear the memtable, since it had // invalid chunks in it, but we wouldn't purge the hasCache. Later writes which // attempted to reference the chunks which had made it into the hasCache would diff --git a/go/libraries/utils/set/strset_test.go b/go/libraries/utils/set/strset_test.go index f67f970607..e2564d718e 100644 --- a/go/libraries/utils/set/strset_test.go +++ b/go/libraries/utils/set/strset_test.go @@ -48,7 +48,7 @@ func TestStrSet(t *testing.T) { t.Error("Set doesn't match expectation after removes", strSet.AsSlice()) } - strSet.Remove("non-existant string") + strSet.Remove("non-existent string") if !isAsExpected(strSet, []string{"a", "c", "e"}) { t.Error("Set doesn't match expectation after noop remove", strSet.AsSlice()) diff --git a/go/store/types/apply_map_edits.go b/go/store/types/apply_map_edits.go index 09b125dbdd..f9e7d7b1b8 100644 --- a/go/store/types/apply_map_edits.go +++ b/go/store/types/apply_map_edits.go @@ -94,7 +94,7 @@ type AppliedEditStats struct { // Deletions counts the number of items deleted from the map Deletions int64 - // NonexistantDeletes counts the number of items where a deletion was attempted, but the key didn't exist in the map + // NonexistentDeletes counts the number of items where a deletion was attempted, but the key didn't exist in the map // so there was no impact NonExistentDeletes int64 } diff --git a/integration-tests/bats/1pk5col-ints.bats b/integration-tests/bats/1pk5col-ints.bats index 8356231332..3a4896d217 100755 --- a/integration-tests/bats/1pk5col-ints.bats +++ b/integration-tests/bats/1pk5col-ints.bats @@ -680,7 +680,7 @@ DELIM [[ "$output" =~ "PRIMARY KEY (\`pk\`)" ]] || false } -@test "1pk5col-ints: dolt schema show on non existant table" { +@test "1pk5col-ints: dolt schema show on non existent table" { run dolt schema show foo [ "$status" -eq 0 ] [ "$output" = "foo not found" ] diff --git a/integration-tests/bats/conflict-detection.bats b/integration-tests/bats/conflict-detection.bats index 84cb992fd7..d09ba594a6 100644 --- a/integration-tests/bats/conflict-detection.bats +++ b/integration-tests/bats/conflict-detection.bats @@ -9,7 +9,7 @@ teardown() { teardown_common } -@test "conflict-detection: merge non-existant branch errors" { +@test "conflict-detection: merge non-existent branch errors" { run dolt merge batmans-parents [ $status -eq 1 ] [[ "$output" =~ "branch not found" ]] || false diff --git a/integration-tests/bats/create-views.bats b/integration-tests/bats/create-views.bats index e104202301..98d360caf3 100644 --- a/integration-tests/bats/create-views.bats +++ b/integration-tests/bats/create-views.bats @@ -139,7 +139,7 @@ SQL [[ "${lines[3]}" =~ ' 4 ' ]] || false } -@test "create-views: cannot create view referencing non-existant table" { +@test "create-views: cannot create view referencing non-existent table" { run dolt sql < Date: Fri, 1 Dec 2023 19:26:45 +0000 Subject: [PATCH 13/17] [ga-bump-dep] Bump dependency in Dolt by tbantle22 --- go/go.mod | 2 +- go/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/go.mod b/go/go.mod index ff7c300a18..e24c83c68d 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.17.1-0.20231201021351-97a2867b8225 + github.com/dolthub/go-mysql-server v0.17.1-0.20231201192511-a3ee71b20029 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 cf1ad94a2b..dfa44b7261 100644 --- a/go/go.sum +++ b/go/go.sum @@ -181,8 +181,8 @@ github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U= github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0= github.com/dolthub/go-icu-regex v0.0.0-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.17.1-0.20231201021351-97a2867b8225 h1:6+FqniHHZRWNfuXtIlvSLUWoZhJEixyWYcgSsPlT69U= -github.com/dolthub/go-mysql-server v0.17.1-0.20231201021351-97a2867b8225/go.mod h1:vXlRKS39WHav9N51VsfYphKhmSA2t5FkhHmW3BtwH5I= +github.com/dolthub/go-mysql-server v0.17.1-0.20231201192511-a3ee71b20029 h1:Y8fx0dGnjI6QU+SAzyytzExQQP53dpcedMdwFNxIcxc= +github.com/dolthub/go-mysql-server v0.17.1-0.20231201192511-a3ee71b20029/go.mod h1:vXlRKS39WHav9N51VsfYphKhmSA2t5FkhHmW3BtwH5I= 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 80a8e1db4808eaa36f913ff2564a8f9007b633d9 Mon Sep 17 00:00:00 2001 From: reltuk Date: Fri, 1 Dec 2023 21:19:21 +0000 Subject: [PATCH 14/17] [ga-bump-release] Update Dolt version to 1.29.0 and release v1.29.0 --- go/cmd/dolt/dolt.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/dolt/dolt.go b/go/cmd/dolt/dolt.go index ec54b65ff0..0208d0402c 100644 --- a/go/cmd/dolt/dolt.go +++ b/go/cmd/dolt/dolt.go @@ -64,7 +64,7 @@ import ( ) const ( - Version = "1.28.2" + Version = "1.29.0" ) var dumpDocsCommand = &commands.DumpDocsCmd{} From b47eeb4decca51a145ba992e29ad0759fefcbe9a Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Fri, 1 Dec 2023 15:00:05 -0800 Subject: [PATCH 15/17] PR comments --- go/cmd/dolt/commands/reflog.go | 30 ++++----- .../doltcore/sqle/reflog_table_function.go | 66 ++++++++----------- integration-tests/bats/reflog.bats | 17 +++++ 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/go/cmd/dolt/commands/reflog.go b/go/cmd/dolt/commands/reflog.go index 0653aba3fd..4c07cfe773 100644 --- a/go/cmd/dolt/commands/reflog.go +++ b/go/cmd/dolt/commands/reflog.go @@ -136,12 +136,12 @@ type ReflogInfo struct { func printReflog(rows []sql.Row, queryist cli.Queryist, sqlCtx *sql.Context) int { var reflogInfo []ReflogInfo - // Get the current branch - curBranch := "" - res, err := GetRowsForSql(queryist, sqlCtx, "SELECT active_branch()") + // Get the hash of HEAD for the `HEAD ->` decoration + headHash := "" + res, err := GetRowsForSql(queryist, sqlCtx, "SELECT hashof('HEAD')") if err == nil { - // still print the reflog even if we can't get the current branch - curBranch = res[0][0].(string) + // still print the reflog even if we can't get the hash + headHash = res[0][0].(string) } for _, row := range rows { @@ -151,13 +151,13 @@ func printReflog(rows []sql.Row, queryist cli.Queryist, sqlCtx *sql.Context) int reflogInfo = append(reflogInfo, ReflogInfo{ref, commitHash, commitMessage}) } - reflogToStdOut(reflogInfo, curBranch) + reflogToStdOut(reflogInfo, headHash) return 0 } // reflogToStdOut takes a list of ReflogInfo and prints the reflog to stdout -func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) { +func reflogToStdOut(reflogInfo []ReflogInfo, headHash string) { if cli.ExecuteWithStdioRestored == nil { return } @@ -169,8 +169,12 @@ func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) { // TODO: use short hash instead line := []string{fmt.Sprintf("\033[33m%s\033[0m", info.commitHash)} // commit hash in yellow (33m) - processedRef := processRefForReflog(info.ref, curBranch) - line = append(line, fmt.Sprintf("\033[33m(%s\033[33m)\033[0m", processedRef)) // () in yellow (33m) + processedRef := processRefForReflog(info.ref) + if headHash != "" && headHash == info.commitHash { + line = append(line, fmt.Sprintf("\033[33m(\033[36;1mHEAD -> %s\033[33m)\033[0m", processedRef)) // HEAD in cyan (36;1) + } else { + line = append(line, fmt.Sprintf("\033[33m(%s\033[33m)\033[0m", processedRef)) // () in yellow (33m) + } line = append(line, fmt.Sprintf("%s\n", info.commitMessage)) pager.Writer.Write([]byte(strings.Join(line, " "))) } @@ -178,13 +182,9 @@ func reflogToStdOut(reflogInfo []ReflogInfo, curBranch string) { } // processRefForReflog takes a full ref (e.g. refs/heads/master) or tag name and returns the ref name (e.g. master) with relevant decoration. -func processRefForReflog(fullRef string, curBranch string) string { +func processRefForReflog(fullRef string) string { if strings.HasPrefix(fullRef, "refs/heads/") { - branch := strings.TrimPrefix(fullRef, "refs/heads/") - if curBranch != "" && branch == curBranch { - return fmt.Sprintf("\033[36;1mHEAD -> \033[32;1m%s\033[0m", branch) // HEAD in cyan (36;1), branch in green (32;1m) - } - return fmt.Sprintf("\033[32;1m%s\033[0m", branch) // branch in green (32;1m) + return fmt.Sprintf("\033[32;1m%s\033[0m", strings.TrimPrefix(fullRef, "refs/heads/")) // branch in green (32;1m) } else if strings.HasPrefix(fullRef, "refs/tags/") { return fmt.Sprintf("\033[33mtag: %s\033[0m", strings.TrimPrefix(fullRef, "refs/tags/")) // tag in yellow (33m) } else if strings.HasPrefix(fullRef, "refs/remotes/") { diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index f0124a84bf..5e9ef5f37d 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -29,10 +29,9 @@ import ( ) type ReflogTableFunction struct { - ctx *sql.Context - database sql.Database - refExpr sql.Expression - showAll bool + ctx *sql.Context + database sql.Database + refAndArgExprs []sql.Expression } var _ sql.TableFunction = (*ReflogTableFunction)(nil) @@ -66,17 +65,30 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row } var refName string - if rltf.refExpr != nil { - target, err := rltf.refExpr.Eval(ctx, row) + showAll := false + for _, expr := range rltf.refAndArgExprs { + target, err := expr.Eval(ctx, row) if err != nil { return nil, fmt.Errorf("error evaluating expression (%s): %s", - rltf.refExpr.String(), err.Error()) + expr.String(), err.Error()) } - - refName, ok = target.(string) + targetStr, ok := target.(string) if !ok { return nil, fmt.Errorf("argument (%v) is not a string value, but a %T", target, target) } + + if targetStr == "--all" { + if showAll { + return nil, fmt.Errorf("error: multiple values provided for `all`") + } + showAll = true + } else { + if refName != "" { + return nil, fmt.Errorf("error: %s has too many positional arguments. Expected at most %d, found %d: %s", + rltf.Name(), 1, 2, rltf.refAndArgExprs) + } + refName = targetStr + } } ddb := sqlDb.DbData().Ddb @@ -112,7 +124,7 @@ func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.Row } // skip workspace refs by default if doltRef.GetType() == ref.WorkspaceRefType { - if !rltf.showAll { + if !showAll { return nil } } @@ -179,19 +191,17 @@ func (rltf *ReflogTableFunction) Schema() sql.Schema { } func (rltf *ReflogTableFunction) Resolved() bool { - if rltf.refExpr != nil { - return rltf.refExpr.Resolved() + for _, expr := range rltf.refAndArgExprs { + return expr.Resolved() } return true } func (rltf *ReflogTableFunction) String() string { var args []string - if rltf.showAll { - args = append(args, "'--all'") - } - if rltf.refExpr != nil { - args = append(args, rltf.refExpr.String()) + + for _, expr := range rltf.refAndArgExprs { + args = append(args, expr.String()) } return fmt.Sprintf("DOLT_REFLOG(%s)", strings.Join(args, ", ")) } @@ -218,10 +228,7 @@ func (rltf *ReflogTableFunction) IsReadOnly() bool { } func (rltf *ReflogTableFunction) Expressions() []sql.Expression { - if rltf.refExpr != nil { - return []sql.Expression{rltf.refExpr} - } - return []sql.Expression{} + return rltf.refAndArgExprs } func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) (sql.Node, error) { @@ -230,22 +237,7 @@ func (rltf *ReflogTableFunction) WithExpressions(expression ...sql.Expression) ( } new := *rltf - - if len(expression) == 2 { - if expression[0].String() == "'--all'" && expression[1].String() == "'--all'" { - return nil, fmt.Errorf("error: multiple values provided for `all`") - } - if expression[0].String() != "'--all'" && expression[1].String() != "'--all'" { - return nil, fmt.Errorf("error: %s has too many positional arguments. Expected at most %d, found %d: %s", rltf.Name(), 1, 2, expression) - } - } - for _, expr := range expression { - if expr.String() != "'--all'" { - new.refExpr = expr - } else { - new.showAll = true - } - } + new.refAndArgExprs = expression return &new, nil } diff --git a/integration-tests/bats/reflog.bats b/integration-tests/bats/reflog.bats index 93d54fda02..942f983466 100755 --- a/integration-tests/bats/reflog.bats +++ b/integration-tests/bats/reflog.bats @@ -241,3 +241,20 @@ SQL [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 0 ] } + +@test "reflog: 'HEAD -> ' decoration only appears on HEAD entries" { + setup_common + + dolt sql -q "create table t (i int primary key, j int);" + dolt sql -q "insert into t values (1, 1), (2, 2), (3, 3)"; + dolt commit -Am "initial commit" + + run dolt reflog + [ "$status" -eq 0 ] + [ "${#lines[@]}" -eq 2 ] + line1=$(echo "${lines[0]}" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + line2=$(echo "${lines[1]}" | sed -E 's/\x1b\[[0-9;]*m//g') # remove special characters for color + [[ "$line1" =~ "(HEAD -> main) initial commit" ]] || false + [[ "$line2" =~ "Initialize data repository" ]] || false + [[ ! "$line2" =~ "HEAD" ]] || false +} From a99b52dc9e841c5a48797a62b5d3e2523cc04e15 Mon Sep 17 00:00:00 2001 From: Stephanie You Date: Fri, 1 Dec 2023 15:44:34 -0800 Subject: [PATCH 16/17] small fix --- go/libraries/doltcore/sqle/reflog_table_function.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index 46b89a2abd..874f7d786c 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -214,7 +214,9 @@ func (rltf *ReflogTableFunction) Schema() sql.Schema { func (rltf *ReflogTableFunction) Resolved() bool { for _, expr := range rltf.refAndArgExprs { - return expr.Resolved() + if !expr.Resolved() { + return false + } } return true } From 7572724aa3f2e29401c6b5c91a173530d2a29138 Mon Sep 17 00:00:00 2001 From: Maximilian Hoffman Date: Fri, 1 Dec 2023 16:22:57 -0800 Subject: [PATCH 17/17] [no-release-notes] Unique ids cleanup bump (#7086) * [no-release-notes] Unique ids cleanup bump * [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh * bump again --------- Co-authored-by: max-hoffman --- go/go.mod | 2 +- go/go.sum | 4 ++-- .../sqle/dolt_diff_stat_table_function.go | 22 ------------------ .../sqle/dolt_diff_summary_table_function.go | 22 ------------------ .../doltcore/sqle/dolt_diff_table_function.go | 23 ------------------- .../doltcore/sqle/dolt_log_table_function.go | 23 ------------------- .../sqle/dolt_patch_table_function.go | 22 ------------------ .../sqle/dolt_query_diff_table_function.go | 23 ------------------- .../sqle/dolt_schema_diff_table_function.go | 22 ------------------ .../sqle/enginetest/dolt_engine_test.go | 2 +- go/libraries/doltcore/sqle/history_table.go | 1 - .../doltcore/sqle/reflog_table_function.go | 22 ------------------ 12 files changed, 4 insertions(+), 184 deletions(-) diff --git a/go/go.mod b/go/go.mod index e24c83c68d..6e97ce243b 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.17.1-0.20231201192511-a3ee71b20029 + github.com/dolthub/go-mysql-server v0.17.1-0.20231201211641-8889517a6d60 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 dfa44b7261..be89dd7609 100644 --- a/go/go.sum +++ b/go/go.sum @@ -181,8 +181,8 @@ github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U= github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0= github.com/dolthub/go-icu-regex v0.0.0-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.17.1-0.20231201192511-a3ee71b20029 h1:Y8fx0dGnjI6QU+SAzyytzExQQP53dpcedMdwFNxIcxc= -github.com/dolthub/go-mysql-server v0.17.1-0.20231201192511-a3ee71b20029/go.mod h1:vXlRKS39WHav9N51VsfYphKhmSA2t5FkhHmW3BtwH5I= +github.com/dolthub/go-mysql-server v0.17.1-0.20231201211641-8889517a6d60 h1:4oj5xEB5anIEfFa2PXSMnb2jELIcnB4mexIeozmKyZM= +github.com/dolthub/go-mysql-server v0.17.1-0.20231201211641-8889517a6d60/go.mod h1:vXlRKS39WHav9N51VsfYphKhmSA2t5FkhHmW3BtwH5I= 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= diff --git a/go/libraries/doltcore/sqle/dolt_diff_stat_table_function.go b/go/libraries/doltcore/sqle/dolt_diff_stat_table_function.go index 984910354e..4a0368feb1 100644 --- a/go/libraries/doltcore/sqle/dolt_diff_stat_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_diff_stat_table_function.go @@ -45,8 +45,6 @@ type DiffStatTableFunction struct { dotCommitExpr sql.Expression tableNameExpr sql.Expression database sql.Database - tabId sql.TableId - colset sql.ColSet } var diffStatTableSchema = sql.Schema{ @@ -79,26 +77,6 @@ func (ds *DiffStatTableFunction) NewInstance(ctx *sql.Context, db sql.Database, return node, nil } -func (ds *DiffStatTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *ds - ret.tabId = id - return &ret -} - -func (ds *DiffStatTableFunction) Id() sql.TableId { - return ds.tabId -} - -func (ds *DiffStatTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *ds - ds.colset = set - return &ret -} - -func (ds *DiffStatTableFunction) Columns() sql.ColSet { - return ds.colset -} - func (ds *DiffStatTableFunction) DataLength(ctx *sql.Context) (uint64, error) { numBytesPerRow := schema.SchemaAvgLength(ds.Schema()) numRows, _, err := ds.RowCount(ctx) diff --git a/go/libraries/doltcore/sqle/dolt_diff_summary_table_function.go b/go/libraries/doltcore/sqle/dolt_diff_summary_table_function.go index 58c12ed72a..f46243da93 100644 --- a/go/libraries/doltcore/sqle/dolt_diff_summary_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_diff_summary_table_function.go @@ -42,8 +42,6 @@ type DiffSummaryTableFunction struct { dotCommitExpr sql.Expression tableNameExpr sql.Expression database sql.Database - tabId sql.TableId - colset sql.ColSet } var diffSummaryTableSchema = sql.Schema{ @@ -69,26 +67,6 @@ func (ds *DiffSummaryTableFunction) NewInstance(ctx *sql.Context, db sql.Databas return node, nil } -func (ds *DiffSummaryTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *ds - ret.tabId = id - return &ret -} - -func (ds *DiffSummaryTableFunction) Id() sql.TableId { - return ds.tabId -} - -func (ds *DiffSummaryTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *ds - ret.colset = set - return &ret -} - -func (ds *DiffSummaryTableFunction) Columns() sql.ColSet { - return ds.colset -} - func (ds *DiffSummaryTableFunction) DataLength(ctx *sql.Context) (uint64, error) { numBytesPerRow := schema.SchemaAvgLength(ds.Schema()) numRows, _, err := ds.RowCount(ctx) diff --git a/go/libraries/doltcore/sqle/dolt_diff_table_function.go b/go/libraries/doltcore/sqle/dolt_diff_table_function.go index 589a084819..1e00654aa0 100644 --- a/go/libraries/doltcore/sqle/dolt_diff_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_diff_table_function.go @@ -54,29 +54,6 @@ type DiffTableFunction struct { tableDelta diff.TableDelta fromDate *types.Timestamp toDate *types.Timestamp - - tabId sql.TableId - colset sql.ColSet -} - -func (dtf *DiffTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *dtf - ret.tabId = id - return &ret -} - -func (dtf *DiffTableFunction) Id() sql.TableId { - return dtf.tabId -} - -func (dtf *DiffTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *dtf - ret.colset = set - return &ret -} - -func (dtf *DiffTableFunction) Columns() sql.ColSet { - return dtf.colset } // NewInstance creates a new instance of TableFunction interface diff --git a/go/libraries/doltcore/sqle/dolt_log_table_function.go b/go/libraries/doltcore/sqle/dolt_log_table_function.go index 4bd45f95fe..2ee03a3680 100644 --- a/go/libraries/doltcore/sqle/dolt_log_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_log_table_function.go @@ -48,9 +48,6 @@ type LogTableFunction struct { showParents bool decoration string - tabId sql.TableId - colset sql.ColSet - database sql.Database } @@ -77,26 +74,6 @@ func (ltf *LogTableFunction) NewInstance(ctx *sql.Context, db sql.Database, expr return node, nil } -func (ltf *LogTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *ltf - ret.tabId = id - return &ret -} - -func (ltf *LogTableFunction) Id() sql.TableId { - return ltf.tabId -} - -func (ltf *LogTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *ltf - ret.colset = set - return &ret -} - -func (ltf *LogTableFunction) Columns() sql.ColSet { - return ltf.colset -} - // Database implements the sql.Databaser interface func (ltf *LogTableFunction) Database() sql.Database { return ltf.database diff --git a/go/libraries/doltcore/sqle/dolt_patch_table_function.go b/go/libraries/doltcore/sqle/dolt_patch_table_function.go index 00631e5f52..d047ab799d 100644 --- a/go/libraries/doltcore/sqle/dolt_patch_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_patch_table_function.go @@ -74,28 +74,6 @@ type PatchTableFunction struct { dotCommitExpr sql.Expression tableNameExpr sql.Expression database sql.Database - tabId sql.TableId - colset sql.ColSet -} - -func (p *PatchTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *p - ret.tabId = id - return &ret -} - -func (p *PatchTableFunction) Id() sql.TableId { - return p.tabId -} - -func (p *PatchTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *p - ret.colset = set - return &ret -} - -func (p *PatchTableFunction) Columns() sql.ColSet { - return p.colset } func (p *PatchTableFunction) DataLength(ctx *sql.Context) (uint64, error) { diff --git a/go/libraries/doltcore/sqle/dolt_query_diff_table_function.go b/go/libraries/doltcore/sqle/dolt_query_diff_table_function.go index 777c62fe6b..64e1adb45f 100644 --- a/go/libraries/doltcore/sqle/dolt_query_diff_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_query_diff_table_function.go @@ -45,29 +45,6 @@ type QueryDiffTableFunction struct { rowIter2 sql.RowIter schema1 sql.Schema schema2 sql.Schema - - tabId sql.TableId - colset sql.ColSet -} - -func (tf *QueryDiffTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *tf - ret.tabId = id - return &ret -} - -func (tf *QueryDiffTableFunction) Id() sql.TableId { - return tf.tabId -} - -func (tf *QueryDiffTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *tf - ret.colset = set - return &ret -} - -func (tf *QueryDiffTableFunction) Columns() sql.ColSet { - return tf.colset } // NewInstance creates a new instance of TableFunction interface diff --git a/go/libraries/doltcore/sqle/dolt_schema_diff_table_function.go b/go/libraries/doltcore/sqle/dolt_schema_diff_table_function.go index 8b3dbaa619..4427ef01f5 100644 --- a/go/libraries/doltcore/sqle/dolt_schema_diff_table_function.go +++ b/go/libraries/doltcore/sqle/dolt_schema_diff_table_function.go @@ -60,9 +60,6 @@ type SchemaDiffTableFunction struct { tableNameExpr sql.Expression database sql.Database - - tabId sql.TableId - colset sql.ColSet } var schemaDiffTableSchema = sql.Schema{ @@ -87,25 +84,6 @@ func (ds *SchemaDiffTableFunction) NewInstance(ctx *sql.Context, db sql.Database return node, nil } -func (ds *SchemaDiffTableFunction) WithId(id sql.TableId) sql.TableIdNode { - //TODO implement me - panic("implement me") -} - -func (ds *SchemaDiffTableFunction) Id() sql.TableId { - return ds.tabId -} - -func (ds *SchemaDiffTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *ds - ds.colset = set - return &ret -} - -func (ds *SchemaDiffTableFunction) Columns() sql.ColSet { - return ds.colset -} - func (ds *SchemaDiffTableFunction) DataLength(ctx *sql.Context) (uint64, error) { numBytesPerRow := schema.SchemaAvgLength(ds.Schema()) numRows, _, err := ds.RowCount(ctx) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 85ad41ce2f..71d0a9f8be 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -1984,7 +1984,7 @@ func TestBrokenSystemTableQueries(t *testing.T) { } func TestHistorySystemTable(t *testing.T) { - harness := newDoltHarness(t).WithParallelism(1) + harness := newDoltHarness(t).WithParallelism(2) defer harness.Close() harness.Setup(setup.MydbData) for _, test := range HistorySystemTableScriptTests { diff --git a/go/libraries/doltcore/sqle/history_table.go b/go/libraries/doltcore/sqle/history_table.go index d79bb44a7a..e3986ab5ca 100644 --- a/go/libraries/doltcore/sqle/history_table.go +++ b/go/libraries/doltcore/sqle/history_table.go @@ -419,7 +419,6 @@ func (ht *HistoryTable) Collation() sql.CollationID { // Partitions returns a PartitionIter which will be used in getting partitions each of which is used to create RowIter. func (ht *HistoryTable) Partitions(ctx *sql.Context) (sql.PartitionIter, error) { - // TODO reset ht.cmItr on close iter, err := ht.filterIter(ctx, ht.cmItr) if err != nil { return nil, err diff --git a/go/libraries/doltcore/sqle/reflog_table_function.go b/go/libraries/doltcore/sqle/reflog_table_function.go index b6a868215e..64b23a4de4 100644 --- a/go/libraries/doltcore/sqle/reflog_table_function.go +++ b/go/libraries/doltcore/sqle/reflog_table_function.go @@ -32,8 +32,6 @@ type ReflogTableFunction struct { ctx *sql.Context database sql.Database refExpr sql.Expression - tabId sql.TableId - colset sql.ColSet } var _ sql.TableFunction = (*ReflogTableFunction)(nil) @@ -60,26 +58,6 @@ func (rltf *ReflogTableFunction) NewInstance(ctx *sql.Context, database sql.Data return node, nil } -func (rltf *ReflogTableFunction) WithId(id sql.TableId) sql.TableIdNode { - ret := *rltf - ret.tabId = id - return &ret -} - -func (rltf *ReflogTableFunction) Id() sql.TableId { - return rltf.tabId -} - -func (rltf *ReflogTableFunction) WithColumns(set sql.ColSet) sql.TableIdNode { - ret := *rltf - ret.colset = set - return &ret -} - -func (rltf *ReflogTableFunction) Columns() sql.ColSet { - return rltf.colset -} - func (rltf *ReflogTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) { sqlDb, ok := rltf.database.(dsess.SqlDatabase) if !ok {