github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/rowexec/backfiller_test.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package rowexec_test
    12  
    13  import (
    14  	"context"
    15  	"testing"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/base"
    18  	"github.com/cockroachdb/cockroach/pkg/jobs"
    19  	"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
    20  	"github.com/cockroachdb/cockroach/pkg/keys"
    21  	"github.com/cockroachdb/cockroach/pkg/kv"
    22  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    23  	"github.com/cockroachdb/cockroach/pkg/sql"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/backfill"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/rowexec"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    27  	"github.com/cockroachdb/cockroach/pkg/sqlmigrations"
    28  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    29  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    30  	"github.com/cockroachdb/errors"
    31  )
    32  
    33  func TestWriteResumeSpan(t *testing.T) {
    34  	defer leaktest.AfterTest(t)()
    35  
    36  	ctx := context.Background()
    37  
    38  	server, sqlDB, kvDB := serverutils.StartServer(t, base.TestServerArgs{
    39  		Knobs: base.TestingKnobs{
    40  			// Disable all schema change execution.
    41  			SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{
    42  				SchemaChangeJobNoOp: func() bool {
    43  					return true
    44  				},
    45  			},
    46  			// Disable backfill migrations, we still need the jobs table migration.
    47  			SQLMigrationManager: &sqlmigrations.MigrationManagerTestingKnobs{
    48  				DisableBackfillMigrations: true,
    49  			},
    50  		},
    51  	})
    52  	defer server.Stopper().Stop(ctx)
    53  
    54  	if _, err := sqlDB.Exec(`
    55  	CREATE DATABASE t;
    56  	CREATE TABLE t.test (k INT PRIMARY KEY, v INT);
    57  	CREATE UNIQUE INDEX vidx ON t.test (v);
    58  	`); err != nil {
    59  		t.Fatal(err)
    60  	}
    61  
    62  	resumeSpans := []roachpb.Span{
    63  		{Key: roachpb.Key("a"), EndKey: roachpb.Key("b")},
    64  		{Key: roachpb.Key("c"), EndKey: roachpb.Key("d")},
    65  		{Key: roachpb.Key("e"), EndKey: roachpb.Key("f")},
    66  		{Key: roachpb.Key("g"), EndKey: roachpb.Key("h")},
    67  		{Key: roachpb.Key("i"), EndKey: roachpb.Key("j")},
    68  		{Key: roachpb.Key("k"), EndKey: roachpb.Key("l")},
    69  		{Key: roachpb.Key("m"), EndKey: roachpb.Key("n")},
    70  		{Key: roachpb.Key("o"), EndKey: roachpb.Key("p")},
    71  		{Key: roachpb.Key("q"), EndKey: roachpb.Key("r")},
    72  	}
    73  
    74  	registry := server.JobRegistry().(*jobs.Registry)
    75  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
    76  
    77  	if err := kvDB.Put(
    78  		ctx,
    79  		sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, tableDesc.ID),
    80  		sqlbase.WrapDescriptor(tableDesc),
    81  	); err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	mutationID := tableDesc.Mutations[0].MutationID
    86  	var jobID int64
    87  
    88  	if len(tableDesc.MutationJobs) > 0 {
    89  		for _, job := range tableDesc.MutationJobs {
    90  			if job.MutationID == mutationID {
    91  				jobID = job.JobID
    92  				break
    93  			}
    94  		}
    95  	}
    96  
    97  	details := jobspb.SchemaChangeDetails{ResumeSpanList: []jobspb.ResumeSpanList{
    98  		{ResumeSpans: resumeSpans}}}
    99  
   100  	job, err := registry.LoadJob(ctx, jobID)
   101  
   102  	if err != nil {
   103  		t.Fatal(errors.Wrapf(err, "can't find job %d", jobID))
   104  	}
   105  
   106  	err = job.SetDetails(ctx, details)
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	testData := []struct {
   112  		orig   roachpb.Span
   113  		resume roachpb.Span
   114  	}{
   115  		// Work performed in the middle of a span.
   116  		{orig: roachpb.Span{Key: roachpb.Key("a1"), EndKey: roachpb.Key("a3")},
   117  			resume: roachpb.Span{Key: roachpb.Key("a2"), EndKey: roachpb.Key("a3")}},
   118  		// Work completed in the middle of a span.
   119  		{orig: roachpb.Span{Key: roachpb.Key("c1"), EndKey: roachpb.Key("c2")},
   120  			resume: roachpb.Span{}},
   121  		// Work performed in the right of a span.
   122  		{orig: roachpb.Span{Key: roachpb.Key("e1"), EndKey: roachpb.Key("f")},
   123  			resume: roachpb.Span{Key: roachpb.Key("e2"), EndKey: roachpb.Key("f")}},
   124  		// Work completed in the right of a span.
   125  		{orig: roachpb.Span{Key: roachpb.Key("g1"), EndKey: roachpb.Key("h")},
   126  			resume: roachpb.Span{}},
   127  		// Work performed in the left of a span.
   128  		{orig: roachpb.Span{Key: roachpb.Key("i"), EndKey: roachpb.Key("i2")},
   129  			resume: roachpb.Span{Key: roachpb.Key("i1"), EndKey: roachpb.Key("i2")}},
   130  		// Work completed in the left of a span.
   131  		{orig: roachpb.Span{Key: roachpb.Key("k"), EndKey: roachpb.Key("k2")},
   132  			resume: roachpb.Span{}},
   133  		// Work performed on a span.
   134  		{orig: roachpb.Span{Key: roachpb.Key("m"), EndKey: roachpb.Key("n")},
   135  			resume: roachpb.Span{Key: roachpb.Key("m1"), EndKey: roachpb.Key("n")}},
   136  		// Work completed on a span.
   137  		{orig: roachpb.Span{Key: roachpb.Key("o"), EndKey: roachpb.Key("p")},
   138  			resume: roachpb.Span{}},
   139  	}
   140  	for _, test := range testData {
   141  		finished := test.orig
   142  		if test.resume.Key != nil {
   143  			finished.EndKey = test.resume.Key
   144  		}
   145  		if err := rowexec.WriteResumeSpan(
   146  			ctx, kvDB, keys.SystemSQLCodec, tableDesc.ID, mutationID, backfill.IndexMutationFilter, roachpb.Spans{finished}, registry,
   147  		); err != nil {
   148  			t.Error(err)
   149  		}
   150  	}
   151  
   152  	expected := []roachpb.Span{
   153  		// Work performed in the middle of a span.
   154  		{Key: roachpb.Key("a"), EndKey: roachpb.Key("a1")},
   155  		{Key: roachpb.Key("a2"), EndKey: roachpb.Key("b")},
   156  		// Work completed in the middle of a span.
   157  		{Key: roachpb.Key("c"), EndKey: roachpb.Key("c1")},
   158  		{Key: roachpb.Key("c2"), EndKey: roachpb.Key("d")},
   159  		// Work performed in the right of a span.
   160  		{Key: roachpb.Key("e"), EndKey: roachpb.Key("e1")},
   161  		{Key: roachpb.Key("e2"), EndKey: roachpb.Key("f")},
   162  		// Work completed in the right of a span.
   163  		{Key: roachpb.Key("g"), EndKey: roachpb.Key("g1")},
   164  		// Work performed in the left of a span.
   165  		{Key: roachpb.Key("i1"), EndKey: roachpb.Key("j")},
   166  		// Work completed in the left of a span.
   167  		{Key: roachpb.Key("k2"), EndKey: roachpb.Key("l")},
   168  		// Work performed on a span.
   169  		{Key: roachpb.Key("m1"), EndKey: roachpb.Key("n")},
   170  		// Work completed on a span; ["o", "p"] complete.
   171  		{Key: roachpb.Key("q"), EndKey: roachpb.Key("r")},
   172  	}
   173  
   174  	var got []roachpb.Span
   175  	if err := kvDB.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error {
   176  		var err error
   177  		got, _, _, err = rowexec.GetResumeSpans(
   178  			ctx, registry, txn, keys.SystemSQLCodec, tableDesc.ID, mutationID, backfill.IndexMutationFilter)
   179  		return err
   180  	}); err != nil {
   181  		t.Error(err)
   182  	}
   183  	if len(expected) != len(got) {
   184  		t.Fatalf("expected = %+v\n got = %+v", expected, got)
   185  	}
   186  	for i, e := range expected {
   187  		if !e.EqualValue(got[i]) {
   188  			t.Fatalf("expected = %+v, got = %+v", e, got[i])
   189  		}
   190  	}
   191  }