Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
137948: backup: fix alter backup schedule failing on uri with spaces r=msbutler a=kev-cao

`ALTER BACKUP SCHEDULE` being run on a backup schedule whose URI contains spaces would fail with error `ERROR: parse "'gs://cockroachdb-backup-testing/kevin spacey?AUTH=implicit'": first path segment in URL cannot contain colon`.

This was caused by the fact that despite the `FmtBareStrings` flag being used, the space character is considered one of the "special characters" outlined in its doc that causes the string to remain wrapped with quotes. Passing this quoted string to `url.Parse` fails.

Fixes: #134861

Release note (bug fix): `ALTER BACKUP SCHEDULE` no longer fails on schedules whose collection URI contains a space.

138039: opt: wrap a couple of long lines r=rytaft a=rytaft

This PR also serves to test a recent change to blathers.

Fixes #138038

Release note: None

Co-authored-by: Kevin Cao <kevin.cao@cockroachlabs.com>
Co-authored-by: Rebecca Taft <becca@cockroachlabs.com>
  • Loading branch information
3 people committed Dec 27, 2024
3 parents 067599a + bbac419 + e53eb60 commit 686a8fa
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
29 changes: 17 additions & 12 deletions pkg/backup/alter_backup_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,30 +213,35 @@ func doAlterBackupSchedules(
return err
}

if err := emitAlteredSchedule(s.incJob, s.incStmt, resultsCh); err != nil {
if err := emitAlteredSchedule(ctx, p, s.incJob, s.incStmt, resultsCh); err != nil {
return err
}
}

// Emit the full backup schedule after the incremental.
// This matches behavior in CREATE SCHEDULE FOR BACKUP.
return emitAlteredSchedule(s.fullJob, s.fullStmt, resultsCh)
return emitAlteredSchedule(ctx, p, s.fullJob, s.fullStmt, resultsCh)
}

func emitAlteredSchedule(
job *jobs.ScheduledJob, stmt *tree.Backup, resultsCh chan<- tree.Datums,
ctx context.Context,
p sql.PlanHookState,
job *jobs.ScheduledJob,
stmt *tree.Backup,
resultsCh chan<- tree.Datums,
) error {
to := make([]string, len(stmt.To))
for i, dest := range stmt.To {
to[i] = tree.AsStringWithFlags(dest, tree.FmtBareStrings|tree.FmtShowFullURIs)
exprEval := p.ExprEvaluator("BACKUP")
to, err := exprEval.StringArray(ctx, tree.Exprs(stmt.To))
if err != nil {
return err
}
kmsURIs := make([]string, len(stmt.Options.EncryptionKMSURI))
for i, kmsURI := range stmt.Options.EncryptionKMSURI {
kmsURIs[i] = tree.AsStringWithFlags(kmsURI, tree.FmtBareStrings|tree.FmtShowFullURIs)
kmsURIs, err := exprEval.StringArray(ctx, tree.Exprs(stmt.Options.EncryptionKMSURI))
if err != nil {
return err
}
incDests := make([]string, len(stmt.Options.IncrementalStorage))
for i, incDest := range stmt.Options.IncrementalStorage {
incDests[i] = tree.AsStringWithFlags(incDest, tree.FmtBareStrings|tree.FmtShowFullURIs)
incDests, err := exprEval.StringArray(ctx, tree.Exprs(stmt.Options.IncrementalStorage))
if err != nil {
return err
}
if err := emitSchedule(job, stmt, to, kmsURIs, incDests, resultsCh); err != nil {
return err
Expand Down
38 changes: 37 additions & 1 deletion pkg/backup/alter_backup_schedule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ func TestAlterBackupSchedulePausesIncrementalForNewCollection(t *testing.T) {
fullID, err := strconv.Atoi(rows[1][0])
require.NoError(t, err)

// Artificially resume inc schedule to test if it gets paused after the alter
// Artificially resume inc schedule to test if it gets paused after the alter.
th.sqlDB.Exec(t, `RESUME SCHEDULE $1`, incID)

alterCmd := fmt.Sprintf(`ALTER BACKUP SCHEDULE %d SET INTO 'nodelocal://1/backup/alter-schedule-2';`, fullID)
Expand All @@ -271,6 +271,42 @@ func TestAlterBackupSchedulePausesIncrementalForNewCollection(t *testing.T) {
require.Equal(t, "@daily", fullRecurrence)
}

func TestAlterBackupScheduleWithSQLSpecialCharacters(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)

th, cleanup := newAlterSchedulesTestHelper(t, nil)
defer cleanup()

// Characters that require quoting as specified in mustQuoteMap in
// sql/lexbase/encode.go.
uri := "nodelocal://1/backup/alter ,s{hedu}e"

createCmd := fmt.Sprintf(
"CREATE SCHEDULE FOR BACKUP INTO '%s' WITH"+
" incremental_location = '%s' RECURRING '@hourly' FULL BACKUP '@daily';",
uri, uri,
)
rows := th.sqlDB.QueryStr(t, createCmd)
require.Len(t, rows, 2)
incID, err := strconv.Atoi(rows[0][0])
require.NoError(t, err)
fullID, err := strconv.Atoi(rows[1][0])
require.NoError(t, err)

alterCmd := fmt.Sprintf(
"ALTER BACKUP SCHEDULE %d SET INTO '%s', "+
"SET RECURRING '@daily', SET FULL BACKUP '@weekly';",
fullID, uri,
)
th.sqlDB.Exec(t, alterCmd)

_, incRecurrence := scheduleStatusAndRecurrence(t, th, incID)
_, fullRecurrence := scheduleStatusAndRecurrence(t, th, fullID)
require.Equal(t, "@daily", incRecurrence)
require.Equal(t, "@weekly", fullRecurrence)
}

func scheduleStatusAndRecurrence(
t *testing.T, th *alterSchedulesTestHelper, id int,
) (status string, recurrence string) {
Expand Down
6 changes: 4 additions & 2 deletions pkg/sql/opt/memo/expr_format.go
Original file line number Diff line number Diff line change
Expand Up @@ -1042,9 +1042,11 @@ func (f *ExprFmtCtx) formatScalarWithLabel(
f.Buffer.WriteString(": ")
}
switch scalar.Op() {
case opt.ProjectionsOp, opt.AggregationsOp, opt.UniqueChecksOp, opt.FKChecksOp, opt.KVOptionsOp, opt.FastPathUniqueChecksOp:
case opt.ProjectionsOp, opt.AggregationsOp, opt.UniqueChecksOp, opt.FKChecksOp, opt.KVOptionsOp,
opt.FastPathUniqueChecksOp:
// Omit empty lists (except filters) and special-purpose fast path check expressions.
if scalar.ChildCount() == 0 || (scalar.Op() == opt.FastPathUniqueChecksOp && f.HasFlags(ExprFmtHideFastPathChecks)) {
if scalar.ChildCount() == 0 ||
(scalar.Op() == opt.FastPathUniqueChecksOp && f.HasFlags(ExprFmtHideFastPathChecks)) {
return
}

Expand Down

0 comments on commit 686a8fa

Please sign in to comment.