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

     1  // Copyright 2015 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 sql_test
    12  
    13  import (
    14  	"context"
    15  	gosql "database/sql"
    16  	"fmt"
    17  	"math/rand"
    18  	"testing"
    19  
    20  	"github.com/cockroachdb/cockroach/pkg/base"
    21  	"github.com/cockroachdb/cockroach/pkg/keys"
    22  	"github.com/cockroachdb/cockroach/pkg/kv"
    23  	"github.com/cockroachdb/cockroach/pkg/sql"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/catalog/lease"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/tests"
    28  	"github.com/cockroachdb/cockroach/pkg/testutils"
    29  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    30  	"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
    31  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    32  )
    33  
    34  type mutationTest struct {
    35  	// SQLRunner embeds testing.TB
    36  	testing.TB
    37  	*sqlutils.SQLRunner
    38  	kvDB      *kv.DB
    39  	tableDesc *sqlbase.TableDescriptor
    40  }
    41  
    42  func makeMutationTest(
    43  	t *testing.T, kvDB *kv.DB, db *gosql.DB, tableDesc *sqlbase.TableDescriptor,
    44  ) mutationTest {
    45  	return mutationTest{
    46  		TB:        t,
    47  		SQLRunner: sqlutils.MakeSQLRunner(db),
    48  		kvDB:      kvDB,
    49  		tableDesc: tableDesc,
    50  	}
    51  }
    52  
    53  // checkTableSize checks that the number of key:value pairs stored
    54  // in the table equals e.
    55  func (mt mutationTest) checkTableSize(e int) {
    56  	// Check that there are no hidden values
    57  	tableStartKey := keys.SystemSQLCodec.TablePrefix(uint32(mt.tableDesc.ID))
    58  	tableEndKey := tableStartKey.PrefixEnd()
    59  	if kvs, err := mt.kvDB.Scan(context.Background(), tableStartKey, tableEndKey, 0); err != nil {
    60  		mt.Error(err)
    61  	} else if len(kvs) != e {
    62  		mt.Errorf("expected %d key value pairs, but got %d", e, len(kvs))
    63  	}
    64  }
    65  
    66  // Convert all the mutations into live descriptors for the table
    67  // and write the updated table descriptor to the DB.
    68  func (mt mutationTest) makeMutationsActive() {
    69  	// Remove mutation to check real values in DB using SQL
    70  	if mt.tableDesc.Mutations == nil || len(mt.tableDesc.Mutations) == 0 {
    71  		mt.Fatal("No mutations to make active")
    72  	}
    73  	for _, m := range mt.tableDesc.Mutations {
    74  		if col := m.GetColumn(); col != nil {
    75  			mt.tableDesc.Columns = append(mt.tableDesc.Columns, *col)
    76  		} else if index := m.GetIndex(); index != nil {
    77  			mt.tableDesc.Indexes = append(mt.tableDesc.Indexes, *index)
    78  		} else {
    79  			mt.Fatalf("no descriptor in mutation: %v", m)
    80  		}
    81  	}
    82  	mt.tableDesc.Mutations = nil
    83  	mt.tableDesc.Version++
    84  	if err := mt.tableDesc.ValidateTable(); err != nil {
    85  		mt.Fatal(err)
    86  	}
    87  	if err := mt.kvDB.Put(
    88  		context.Background(),
    89  		sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, mt.tableDesc.ID),
    90  		sqlbase.WrapDescriptor(mt.tableDesc),
    91  	); err != nil {
    92  		mt.Fatal(err)
    93  	}
    94  }
    95  
    96  // writeColumnMutation adds column as a mutation and writes the
    97  // descriptor to the DB.
    98  func (mt mutationTest) writeColumnMutation(column string, m sqlbase.DescriptorMutation) {
    99  	col, _, err := mt.tableDesc.FindColumnByName(tree.Name(column))
   100  	if err != nil {
   101  		mt.Fatal(err)
   102  	}
   103  	for i := range mt.tableDesc.Columns {
   104  		if col.ID == mt.tableDesc.Columns[i].ID {
   105  			// Use [:i:i] to prevent reuse of existing slice, or outstanding refs
   106  			// to ColumnDescriptors may unexpectedly change.
   107  			mt.tableDesc.Columns = append(mt.tableDesc.Columns[:i:i], mt.tableDesc.Columns[i+1:]...)
   108  			break
   109  		}
   110  	}
   111  	m.Descriptor_ = &sqlbase.DescriptorMutation_Column{Column: col}
   112  	mt.writeMutation(m)
   113  }
   114  
   115  // writeMutation writes the mutation to the table descriptor. If the
   116  // State or the Direction is undefined, these values are populated via
   117  // picking random values before the mutation is written.
   118  func (mt mutationTest) writeMutation(m sqlbase.DescriptorMutation) {
   119  	if m.Direction == sqlbase.DescriptorMutation_NONE {
   120  		// randomly pick ADD/DROP mutation if this is the first mutation, or
   121  		// pick the direction already chosen for the first mutation.
   122  		if len(mt.tableDesc.Mutations) > 0 {
   123  			m.Direction = mt.tableDesc.Mutations[0].Direction
   124  		} else {
   125  			m.Direction = sqlbase.DescriptorMutation_DROP
   126  			if rand.Intn(2) == 0 {
   127  				m.Direction = sqlbase.DescriptorMutation_ADD
   128  			}
   129  		}
   130  	}
   131  	if m.State == sqlbase.DescriptorMutation_UNKNOWN {
   132  		// randomly pick DELETE_ONLY/DELETE_AND_WRITE_ONLY state.
   133  		r := rand.Intn(2)
   134  		if r == 0 {
   135  			m.State = sqlbase.DescriptorMutation_DELETE_ONLY
   136  		} else {
   137  			m.State = sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY
   138  		}
   139  	}
   140  	mt.tableDesc.Mutations = append(mt.tableDesc.Mutations, m)
   141  	mt.tableDesc.Version++
   142  	if err := mt.tableDesc.ValidateTable(); err != nil {
   143  		mt.Fatal(err)
   144  	}
   145  	if err := mt.kvDB.Put(
   146  		context.Background(),
   147  		sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, mt.tableDesc.ID),
   148  		sqlbase.WrapDescriptor(mt.tableDesc),
   149  	); err != nil {
   150  		mt.Fatal(err)
   151  	}
   152  }
   153  
   154  // Test that UPSERT with a column mutation that has a default value with a
   155  // NOT NULL constraint can handle the null input to its row fetcher, and
   156  // produces output rows of the correct shape.
   157  // Regression test for #29436.
   158  func TestUpsertWithColumnMutationAndNotNullDefault(t *testing.T) {
   159  	defer leaktest.AfterTest(t)()
   160  	// NB: This test manually adds mutations to a table descriptor to test that
   161  	// other schema changes work in the presence of those mutations. Since there's
   162  	// no job associated with the added mutations, those mutations stay on the
   163  	// table descriptor but don't do anything, which is what we want.
   164  
   165  	// The descriptor changes made must have an immediate effect
   166  	// so disable leases on tables.
   167  	defer lease.TestingDisableTableLeases()()
   168  	// Disable external processing of mutations.
   169  	params, _ := tests.CreateTestServerParams()
   170  	server, sqlDB, kvDB := serverutils.StartServer(t, params)
   171  	defer server.Stopper().Stop(context.Background())
   172  
   173  	if _, err := sqlDB.Exec(`
   174  CREATE DATABASE t;
   175  CREATE TABLE t.test (k VARCHAR PRIMARY KEY DEFAULT 'default', v VARCHAR);
   176  INSERT INTO t.test VALUES('a', 'foo');
   177  ALTER TABLE t.test ADD COLUMN i VARCHAR NOT NULL DEFAULT 'i';
   178  `); err != nil {
   179  		t.Fatal(err)
   180  	}
   181  
   182  	// read table descriptor
   183  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   184  
   185  	mTest := makeMutationTest(t, kvDB, sqlDB, tableDesc)
   186  	// Add column "i" as a mutation in delete/write.
   187  	mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY})
   188  
   189  	// This row will conflict with the original row, and should insert an `i`
   190  	// into the new column.
   191  	mTest.Exec(t, `UPSERT INTO t.test VALUES('a', 'bar') RETURNING k`)
   192  
   193  	// These rows will not conflict.
   194  	mTest.Exec(t, `UPSERT INTO t.test VALUES('b', 'bar') RETURNING k`)
   195  	mTest.Exec(t, `INSERT INTO t.test VALUES('c', 'bar') RETURNING k, v`)
   196  	mTest.Exec(t, `INSERT INTO t.test VALUES('c', 'bar') ON CONFLICT(k) DO UPDATE SET v='qux' RETURNING k`)
   197  
   198  	mTest.CheckQueryResults(t, `SELECT * FROM t.test`, [][]string{
   199  		{"a", "bar"},
   200  		{"b", "bar"},
   201  		{"c", "qux"},
   202  	})
   203  
   204  	mTest.makeMutationsActive()
   205  
   206  	mTest.CheckQueryResults(t, `SELECT * FROM t.test`, [][]string{
   207  		{"a", "bar", "i"},
   208  		{"b", "bar", "i"},
   209  		{"c", "qux", "i"},
   210  	})
   211  }
   212  
   213  // Test INSERT, UPDATE, UPSERT, and DELETE operations with a column schema
   214  // change.
   215  func TestOperationsWithColumnMutation(t *testing.T) {
   216  	defer leaktest.AfterTest(t)()
   217  	// NB: This test manually adds mutations to a table descriptor to test that
   218  	// other schema changes work in the presence of those mutations. Since there's
   219  	// no job associated with the added mutations, those mutations stay on the
   220  	// table descriptor but don't do anything, which is what we want.
   221  
   222  	// The descriptor changes made must have an immediate effect
   223  	// so disable leases on tables.
   224  	defer lease.TestingDisableTableLeases()()
   225  	// Disable external processing of mutations.
   226  	params, _ := tests.CreateTestServerParams()
   227  	server, sqlDB, kvDB := serverutils.StartServer(t, params)
   228  	defer server.Stopper().Stop(context.Background())
   229  
   230  	// Fix the column families so the key counts below don't change if the
   231  	// family heuristics are updated.
   232  	// Add an index so that we test adding a column when a table has an index.
   233  	if _, err := sqlDB.Exec(`
   234  CREATE DATABASE t;
   235  CREATE TABLE t.test (k VARCHAR PRIMARY KEY DEFAULT 'default', v VARCHAR, i VARCHAR DEFAULT 'i', FAMILY (k), FAMILY (v), FAMILY (i));
   236  CREATE INDEX allidx ON t.test (k, v);
   237  `); err != nil {
   238  		t.Fatal(err)
   239  	}
   240  
   241  	// read table descriptor
   242  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   243  
   244  	mTest := makeMutationTest(t, kvDB, sqlDB, tableDesc)
   245  
   246  	starQuery := `SELECT * FROM t.test`
   247  	for _, useUpsert := range []bool{true, false} {
   248  		// Run the tests for both states.
   249  		for _, state := range []sqlbase.DescriptorMutation_State{sqlbase.DescriptorMutation_DELETE_ONLY,
   250  			sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY} {
   251  			t.Run(fmt.Sprintf("useUpsert=%t/state=%v", useUpsert, state),
   252  				func(t *testing.T) {
   253  
   254  					// Init table to start state.
   255  					mTest.Exec(t, `TRUNCATE TABLE t.test`)
   256  					// read table descriptor
   257  					mTest.tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   258  
   259  					initRows := [][]string{{"a", "z", "q"}}
   260  					for _, row := range initRows {
   261  						if useUpsert {
   262  							mTest.Exec(t, `UPSERT INTO t.test VALUES ($1, $2, $3)`, row[0], row[1], row[2])
   263  						} else {
   264  							mTest.Exec(t, `INSERT INTO t.test VALUES ($1, $2, $3)`, row[0], row[1], row[2])
   265  						}
   266  					}
   267  					// Check that the table only contains the initRows.
   268  					mTest.CheckQueryResults(t, starQuery, initRows)
   269  
   270  					// Add column "i" as a mutation.
   271  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   272  					// A direct read of column "i" fails.
   273  					if _, err := sqlDB.Query(`SELECT i FROM t.test`); err == nil {
   274  						t.Fatalf("Read succeeded despite column being in %v state", sqlbase.DescriptorMutation{State: state})
   275  					}
   276  					// The table only contains columns "k" and "v".
   277  					mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "z"}})
   278  
   279  					// The column backfill uses Put instead of CPut because it depends on
   280  					// an INSERT of a column in the DELETE_AND_WRITE_ONLY state failing. These two
   281  					// tests guarantee that.
   282  
   283  					var err error
   284  					// Inserting a row into the table while specifying column "i" results in an error.
   285  					if useUpsert {
   286  						_, err = sqlDB.Exec(`UPSERT INTO t.test (k, v, i) VALUES ('b', 'y', 'i')`)
   287  					} else {
   288  						_, err = sqlDB.Exec(`INSERT INTO t.test (k, v, i) VALUES ('b', 'y', 'i')`)
   289  					}
   290  					if !testutils.IsError(err, `column "i" does not exist`) &&
   291  						!testutils.IsError(err, `column "i" is being backfilled`) {
   292  						t.Fatal(err)
   293  					}
   294  					if useUpsert {
   295  						_, err = sqlDB.Exec(`UPSERT INTO t.test (k, v) VALUES ('b', 'y') RETURNING i`)
   296  					} else {
   297  						_, err = sqlDB.Exec(`INSERT INTO t.test (k, v) VALUES ('b', 'y') RETURNING i`)
   298  					}
   299  					if !testutils.IsError(err, `column "i" does not exist`) {
   300  						t.Fatal(err)
   301  					}
   302  
   303  					// Repeating the same without specifying the columns results in a different error.
   304  					if useUpsert {
   305  						_, err = sqlDB.Exec(`UPSERT INTO t.test VALUES ('b', 'y', 'i')`)
   306  					} else {
   307  						_, err = sqlDB.Exec(`INSERT INTO t.test VALUES ('b', 'y', 'i')`)
   308  					}
   309  					if !testutils.IsError(err, "(IN|UP)SERT has more expressions than target columns, 3 expressions for 2 targets") &&
   310  						!testutils.IsError(err, `column "i" is being backfilled`) {
   311  						t.Fatal(err)
   312  					}
   313  
   314  					// Make column "i" live so that it is read.
   315  					mTest.makeMutationsActive()
   316  					// Check that we can read all the rows and columns.
   317  					mTest.CheckQueryResults(t, starQuery, initRows)
   318  
   319  					var afterDefaultInsert, afterInsert, afterUpdate, afterPKUpdate, afterDelete [][]string
   320  					var afterDeleteKeys int
   321  					if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   322  						// The default value of "i" for column "i" is not written.
   323  						afterDefaultInsert = [][]string{{"a", "z", "q"}, {"default", "NULL", "NULL"}}
   324  						// The default value of "i" for column "i" is not written.
   325  						afterInsert = [][]string{{"a", "z", "q"}, {"c", "x", "NULL"}}
   326  						// Update is a noop for column "i".
   327  						afterUpdate = [][]string{{"a", "u", "q"}, {"c", "x", "NULL"}}
   328  						// Update the pk of the second tuple from c to d
   329  						afterPKUpdate = [][]string{{"a", "u", "q"}, {"d", "x", "NULL"}}
   330  						// Delete also deletes column "i".
   331  						afterDelete = [][]string{{"d", "x", "NULL"}}
   332  						afterDeleteKeys = 3
   333  					} else {
   334  						// The default value of "i" for column "i" is written.
   335  						afterDefaultInsert = [][]string{{"a", "z", "q"}, {"default", "NULL", "i"}}
   336  						// The default value of "i" for column "i" is written.
   337  						afterInsert = [][]string{{"a", "z", "q"}, {"c", "x", "i"}}
   338  						// Upsert/update sets column "i" to default value of "i".
   339  						afterUpdate = [][]string{{"a", "u", "i"}, {"c", "x", "i"}}
   340  						afterPKUpdate = [][]string{{"a", "u", "i"}, {"d", "x", "i"}}
   341  						// Delete also deletes column "i".
   342  						afterDelete = [][]string{{"d", "x", "i"}}
   343  						afterDeleteKeys = 4
   344  					}
   345  					// Make column "i" a mutation.
   346  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   347  					// Insert an all-defaults row into the table.
   348  					if useUpsert {
   349  						mTest.Exec(t, `UPSERT INTO t.test DEFAULT VALUES`)
   350  					} else {
   351  						mTest.Exec(t, `INSERT INTO t.test DEFAULT VALUES`)
   352  					}
   353  					// Make column "i" live so that it is read.
   354  					mTest.makeMutationsActive()
   355  					// Notice that the default value of "i" is only written when the
   356  					// descriptor is in the DELETE_AND_WRITE_ONLY state.
   357  					mTest.CheckQueryResults(t, starQuery, afterDefaultInsert)
   358  					// Clean up the all-defaults row
   359  					mTest.Exec(t, `DELETE FROM t.test WHERE k = 'default'`)
   360  
   361  					// Make column "i" a mutation.
   362  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   363  					// Insert a row into the table.
   364  					if useUpsert {
   365  						mTest.Exec(t, `UPSERT INTO t.test VALUES ('c', 'x')`)
   366  					} else {
   367  						mTest.Exec(t, `INSERT INTO t.test VALUES ('c', 'x')`)
   368  					}
   369  					// Make column "i" live so that it is read.
   370  					mTest.makeMutationsActive()
   371  					// Notice that the default value of "i" is only written when the
   372  					// descriptor is in the DELETE_AND_WRITE_ONLY state.
   373  					mTest.CheckQueryResults(t, starQuery, afterInsert)
   374  
   375  					// The column backfill uses Put instead of CPut because it depends on
   376  					// an UPDATE of a column in the DELETE_AND_WRITE_ONLY state failing. This test
   377  					// guarantees that.
   378  
   379  					// Make column "i" a mutation.
   380  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   381  					// Updating column "i" for a row fails.
   382  					if useUpsert {
   383  						_, err := sqlDB.Exec(`UPSERT INTO t.test VALUES ('a', 'u', 'u')`)
   384  						if !testutils.IsError(err, `UPSERT has more expressions than target columns, 3 expressions for 2 targets`) {
   385  							t.Fatal(err)
   386  						}
   387  					} else {
   388  						_, err := sqlDB.Exec(`UPDATE t.test SET (v, i) = ('u', 'u') WHERE k = 'a'`)
   389  						if !testutils.IsError(err, `column "i" does not exist`) &&
   390  							!testutils.IsError(err, `column "i" is being backfilled`) {
   391  							t.Fatal(err)
   392  						}
   393  					}
   394  					// Make column "i" live so that it is read.
   395  					mTest.makeMutationsActive()
   396  					// The above failed update was a noop.
   397  					mTest.CheckQueryResults(t, starQuery, afterInsert)
   398  
   399  					// Make column "i" a mutation.
   400  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   401  					// Update a row without specifying  mutation column "i".
   402  					if useUpsert {
   403  						mTest.Exec(t, `UPSERT INTO t.test VALUES ('a', 'u')`)
   404  					} else {
   405  						mTest.Exec(t, `UPDATE t.test SET v = 'u' WHERE k = 'a'`)
   406  					}
   407  					// Make column "i" live so that it is read.
   408  					mTest.makeMutationsActive()
   409  					// The update to column "v" is seen; there is no effect on column "i".
   410  					mTest.CheckQueryResults(t, starQuery, afterUpdate)
   411  
   412  					// Make column "i" a mutation.
   413  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   414  					// Update primary key of row "c" to be "d"
   415  					mTest.Exec(t, `UPDATE t.test SET k = 'd' WHERE v = 'x'`)
   416  					// Make column "i" live so that it is read.
   417  					mTest.makeMutationsActive()
   418  					mTest.CheckQueryResults(t, starQuery, afterPKUpdate)
   419  
   420  					// Make column "i" a mutation.
   421  					mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   422  					// Delete row "a".
   423  					mTest.Exec(t, `DELETE FROM t.test WHERE k = 'a'`)
   424  					// Make column "i" live so that it is read.
   425  					mTest.makeMutationsActive()
   426  					// Row "a" is deleted.
   427  					mTest.CheckQueryResults(t, starQuery, afterDelete)
   428  					// Check that there are no hidden KV values for row "a",
   429  					// and column "i" for row "a" was deleted.
   430  					mTest.checkTableSize(afterDeleteKeys)
   431  				})
   432  		}
   433  	}
   434  
   435  	// Check that a mutation can only be inserted with an explicit mutation state, and direction.
   436  	tableDesc = mTest.tableDesc
   437  	tableDesc.Mutations = []sqlbase.DescriptorMutation{{}}
   438  	if err := tableDesc.ValidateTable(); !testutils.IsError(err, "mutation in state UNKNOWN, direction NONE, and no column/index descriptor") {
   439  		t.Fatal(err)
   440  	}
   441  	tableDesc.Mutations = []sqlbase.DescriptorMutation{{Descriptor_: &sqlbase.DescriptorMutation_Column{Column: &tableDesc.Columns[len(tableDesc.Columns)-1]}}}
   442  	tableDesc.Columns = tableDesc.Columns[:len(tableDesc.Columns)-1]
   443  	if err := tableDesc.ValidateTable(); !testutils.IsError(err, `mutation in state UNKNOWN, direction NONE, col "i", id 3`) {
   444  		t.Fatal(err)
   445  	}
   446  	tableDesc.Mutations[0].State = sqlbase.DescriptorMutation_DELETE_ONLY
   447  	if err := tableDesc.ValidateTable(); !testutils.IsError(err, `mutation in state DELETE_ONLY, direction NONE, col "i", id 3`) {
   448  		t.Fatal(err)
   449  	}
   450  	tableDesc.Mutations[0].State = sqlbase.DescriptorMutation_UNKNOWN
   451  	tableDesc.Mutations[0].Direction = sqlbase.DescriptorMutation_DROP
   452  	if err := tableDesc.ValidateTable(); !testutils.IsError(err, `mutation in state UNKNOWN, direction DROP, col "i", id 3`) {
   453  		t.Fatal(err)
   454  	}
   455  }
   456  
   457  // writeIndexMutation adds index as a mutation and writes the
   458  // descriptor to the DB.
   459  func (mt mutationTest) writeIndexMutation(index string, m sqlbase.DescriptorMutation) {
   460  	tableDesc := mt.tableDesc
   461  	idx, _, err := tableDesc.FindIndexByName(index)
   462  	if err != nil {
   463  		mt.Fatal(err)
   464  	}
   465  	// The rewrite below potentially invalidates the original object with an overwrite.
   466  	// Clarify what's going on.
   467  	idxCopy := *idx
   468  	for i := range tableDesc.Indexes {
   469  		if idxCopy.ID == tableDesc.Indexes[i].ID {
   470  			tableDesc.Indexes = append(tableDesc.Indexes[:i], tableDesc.Indexes[i+1:]...)
   471  			break
   472  		}
   473  	}
   474  
   475  	m.Descriptor_ = &sqlbase.DescriptorMutation_Index{Index: &idxCopy}
   476  	mt.writeMutation(m)
   477  }
   478  
   479  // Test INSERT, UPDATE, UPSERT, and DELETE operations with an index schema
   480  // change.
   481  func TestOperationsWithIndexMutation(t *testing.T) {
   482  	defer leaktest.AfterTest(t)()
   483  	// NB: This test manually adds mutations to a table descriptor to test that
   484  	// other schema changes work in the presence of those mutations. Since there's
   485  	// no job associated with the added mutations, those mutations stay on the
   486  	// table descriptor but don't do anything, which is what we want.
   487  
   488  	// The descriptor changes made must have an immediate effect.
   489  	defer lease.TestingDisableTableLeases()()
   490  	// Disable external processing of mutations.
   491  	params, _ := tests.CreateTestServerParams()
   492  	server, sqlDB, kvDB := serverutils.StartServer(t, params)
   493  	defer server.Stopper().Stop(context.Background())
   494  
   495  	if _, err := sqlDB.Exec(`
   496  CREATE DATABASE t;
   497  CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR, INDEX foo (v));
   498  `); err != nil {
   499  		t.Fatal(err)
   500  	}
   501  
   502  	// read table descriptor
   503  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   504  
   505  	mTest := makeMutationTest(t, kvDB, sqlDB, tableDesc)
   506  
   507  	starQuery := `SELECT * FROM t.test`
   508  	indexQuery := `SELECT v FROM t.test@foo`
   509  	for _, useUpsert := range []bool{true, false} {
   510  		// See the effect of the operations depending on the state.
   511  		for _, state := range []sqlbase.DescriptorMutation_State{sqlbase.DescriptorMutation_DELETE_ONLY,
   512  			sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY} {
   513  			// Init table with some entries.
   514  			if _, err := sqlDB.Exec(`TRUNCATE TABLE t.test`); err != nil {
   515  				t.Fatal(err)
   516  			}
   517  			// read table descriptor
   518  			mTest.tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   519  
   520  			initRows := [][]string{{"a", "z"}, {"b", "y"}}
   521  			for _, row := range initRows {
   522  				if useUpsert {
   523  					mTest.Exec(t, `UPSERT INTO t.test VALUES ($1, $2)`, row[0], row[1])
   524  				} else {
   525  					mTest.Exec(t, `INSERT INTO t.test VALUES ($1, $2)`, row[0], row[1])
   526  				}
   527  			}
   528  			mTest.CheckQueryResults(t, starQuery, initRows)
   529  			// Index foo is visible.
   530  			mTest.CheckQueryResults(t, indexQuery, [][]string{{"y"}, {"z"}})
   531  
   532  			// Index foo is invisible once it's a mutation.
   533  			mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: state})
   534  			if _, err := sqlDB.Query(indexQuery); !testutils.IsError(err, `index "foo" not found`) {
   535  				t.Fatal(err)
   536  			}
   537  
   538  			// Insert a new entry.
   539  			if useUpsert {
   540  				mTest.Exec(t, `UPSERT INTO t.test VALUES ('c', 'x')`)
   541  			} else {
   542  				mTest.Exec(t, `INSERT INTO t.test VALUES ('c', 'x')`)
   543  			}
   544  			mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "z"}, {"b", "y"}, {"c", "x"}})
   545  
   546  			// Make index "foo" live so that we can read it.
   547  			mTest.makeMutationsActive()
   548  			if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   549  				// "x" didn't get added to the index.
   550  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"y"}, {"z"}})
   551  			} else {
   552  				// "x" got added to the index.
   553  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"x"}, {"y"}, {"z"}})
   554  			}
   555  
   556  			// Make "foo" a mutation.
   557  			mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: state})
   558  			// Update.
   559  			if useUpsert {
   560  				mTest.Exec(t, `UPSERT INTO t.test VALUES ('c', 'w')`)
   561  				// Update "v" to its current value "z" in row "a".
   562  				mTest.Exec(t, `UPSERT INTO t.test VALUES ('a', 'z')`)
   563  			} else {
   564  				mTest.Exec(t, `UPDATE t.test SET v = 'w' WHERE k = 'c'`)
   565  				// Update "v" to its current value "z" in row "a".
   566  				mTest.Exec(t, `UPDATE t.test SET v = 'z' WHERE k = 'a'`)
   567  			}
   568  			mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "z"}, {"b", "y"}, {"c", "w"}})
   569  
   570  			// Make index "foo" live so that we can read it.
   571  			mTest.makeMutationsActive()
   572  			if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   573  				// updating "x" -> "w" will result in "x" being deleted from the index.
   574  				// updating "z" -> "z" results in "z" being deleted from the index.
   575  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"y"}})
   576  			} else {
   577  				// updating "x" -> "w" results in the index updating from "x" -> "w",
   578  				// updating "z" -> "z" is a noop on the index.
   579  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"w"}, {"y"}, {"z"}})
   580  			}
   581  
   582  			// Make "foo" a mutation.
   583  			mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: state})
   584  			// Update the primary key of row "a".
   585  			mTest.Exec(t, `UPDATE t.test SET k = 'd' WHERE v = 'z'`)
   586  			mTest.CheckQueryResults(t, starQuery, [][]string{{"b", "y"}, {"c", "w"}, {"d", "z"}})
   587  
   588  			// Make index "foo" live so that we can read it.
   589  			mTest.makeMutationsActive()
   590  			// Updating the primary key for a row when we're in delete-only won't
   591  			// create a new index entry, and will delete the old one. Otherwise it'll
   592  			// create a new entry and delete the old one.
   593  			if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   594  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"y"}})
   595  			} else {
   596  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"w"}, {"y"}, {"z"}})
   597  			}
   598  
   599  			// Make "foo" a mutation.
   600  			mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: state})
   601  			// Delete row "b".
   602  			mTest.Exec(t, `DELETE FROM t.test WHERE k = 'b'`)
   603  			mTest.CheckQueryResults(t, starQuery, [][]string{{"c", "w"}, {"d", "z"}})
   604  
   605  			// Make index "foo" live so that we can read it.
   606  			mTest.makeMutationsActive()
   607  			// Deleting row "b" deletes "y" from the index.
   608  			if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   609  				mTest.CheckQueryResults(t, indexQuery, [][]string{})
   610  			} else {
   611  				mTest.CheckQueryResults(t, indexQuery, [][]string{{"w"}, {"z"}})
   612  			}
   613  		}
   614  	}
   615  
   616  	// Check that a mutation can only be inserted with an explicit mutation state.
   617  	tableDesc = mTest.tableDesc
   618  	tableDesc.Mutations = []sqlbase.DescriptorMutation{{Descriptor_: &sqlbase.DescriptorMutation_Index{Index: &tableDesc.Indexes[len(tableDesc.Indexes)-1]}}}
   619  	tableDesc.Indexes = tableDesc.Indexes[:len(tableDesc.Indexes)-1]
   620  	if err := tableDesc.ValidateTable(); !testutils.IsError(err, "mutation in state UNKNOWN, direction NONE, index foo, id 2") {
   621  		t.Fatal(err)
   622  	}
   623  }
   624  
   625  // TestOperationsWithColumnAndIndexMutation tests the INSERT, UPDATE, UPSERT,
   626  // and DELETE operations while an index mutation refers to a column mutation.
   627  func TestOperationsWithColumnAndIndexMutation(t *testing.T) {
   628  	defer leaktest.AfterTest(t)()
   629  	// NB: This test manually adds mutations to a table descriptor to test that
   630  	// other schema changes work in the presence of those mutations. Since there's
   631  	// no job associated with the added mutations, those mutations stay on the
   632  	// table descriptor but don't do anything, which is what we want.
   633  
   634  	// The descriptor changes made must have an immediate effect
   635  	// so disable leases on tables.
   636  	defer lease.TestingDisableTableLeases()()
   637  	params, _ := tests.CreateTestServerParams()
   638  	server, sqlDB, kvDB := serverutils.StartServer(t, params)
   639  	defer server.Stopper().Stop(context.Background())
   640  
   641  	// Create a table with column i and an index on v and i. Fix the column
   642  	// families so the key counts below don't change if the family heuristics
   643  	// are updated.
   644  	// Add an index so that we test adding a column when a table has an index.
   645  	if _, err := sqlDB.Exec(`
   646  CREATE DATABASE t;
   647  CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR, i CHAR, INDEX foo (i, v), FAMILY (k), FAMILY (v), FAMILY (i));
   648  CREATE INDEX allidx ON t.test (k, v);
   649  `); err != nil {
   650  		t.Fatal(err)
   651  	}
   652  
   653  	// read table descriptor
   654  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   655  
   656  	mTest := makeMutationTest(t, kvDB, sqlDB, tableDesc)
   657  
   658  	starQuery := `SELECT * FROM t.test`
   659  	indexQuery := `SELECT i FROM t.test@foo`
   660  	for _, useUpsert := range []bool{true, false} {
   661  		// Run the tests for both states for a column and an index.
   662  		for _, state := range []sqlbase.DescriptorMutation_State{
   663  			sqlbase.DescriptorMutation_DELETE_ONLY,
   664  			sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY,
   665  		} {
   666  			for _, idxState := range []sqlbase.DescriptorMutation_State{
   667  				sqlbase.DescriptorMutation_DELETE_ONLY,
   668  				sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY,
   669  			} {
   670  				// Ignore the impossible column in DELETE_ONLY state while index
   671  				// is in the DELETE_AND_WRITE_ONLY state.
   672  				if state == sqlbase.DescriptorMutation_DELETE_ONLY &&
   673  					idxState == sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY {
   674  					continue
   675  				}
   676  				// Init table to start state.
   677  				if _, err := sqlDB.Exec(`TRUNCATE TABLE t.test`); err != nil {
   678  					t.Fatal(err)
   679  				}
   680  
   681  				// read table descriptor
   682  				mTest.tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   683  
   684  				initRows := [][]string{{"a", "z", "q"}, {"b", "y", "r"}}
   685  				for _, row := range initRows {
   686  					if useUpsert {
   687  						mTest.Exec(t, `UPSERT INTO t.test VALUES ($1, $2, $3)`, row[0], row[1], row[2])
   688  					} else {
   689  						mTest.Exec(t, `INSERT INTO t.test VALUES ($1, $2, $3)`, row[0], row[1], row[2])
   690  					}
   691  				}
   692  				// Check that the table only contains the initRows.
   693  				mTest.CheckQueryResults(t, starQuery, initRows)
   694  
   695  				// Add index "foo" as a mutation.
   696  				mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: idxState})
   697  				// Make column "i" a mutation.
   698  				mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   699  
   700  				// Insert a row into the table.
   701  				if useUpsert {
   702  					mTest.Exec(t, `UPSERT INTO t.test VALUES ('c', 'x')`)
   703  				} else {
   704  					mTest.Exec(t, `INSERT INTO t.test VALUES ('c', 'x')`)
   705  				}
   706  
   707  				// Make column "i" and index "foo" live.
   708  				mTest.makeMutationsActive()
   709  				// column "i" has no entry.
   710  				mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "z", "q"}, {"b", "y", "r"}, {"c", "x", "NULL"}})
   711  				if idxState == sqlbase.DescriptorMutation_DELETE_ONLY {
   712  					// No index entry for row "c"
   713  					mTest.CheckQueryResults(t, indexQuery, [][]string{{"q"}, {"r"}})
   714  				} else {
   715  					// Index entry for row "c"
   716  					mTest.CheckQueryResults(t, indexQuery, [][]string{{"NULL"}, {"q"}, {"r"}})
   717  				}
   718  
   719  				// Add index "foo" as a mutation.
   720  				mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: idxState})
   721  				// Make column "i" a mutation.
   722  				mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   723  
   724  				// Updating column "i" for a row fails.
   725  				if useUpsert {
   726  					_, err := sqlDB.Exec(`UPSERT INTO t.test VALUES ('a', 'u', 'u')`)
   727  					if !testutils.IsError(err, `UPSERT has more expressions than target columns, 3 expressions for 2 targets`) {
   728  						t.Error(err)
   729  					}
   730  				} else {
   731  					_, err := sqlDB.Exec(`UPDATE t.test SET (v, i) = ('u', 'u') WHERE k = 'a'`)
   732  					if !testutils.IsError(err, `column "i" does not exist`) &&
   733  						!testutils.IsError(err, `column "i" is being backfilled`) {
   734  						t.Error(err)
   735  					}
   736  				}
   737  
   738  				// Using the mutation column as an index expression is disallowed.
   739  				_, err := sqlDB.Exec(`UPDATE t.test SET v = 'u' WHERE i < 'a'`)
   740  				if !testutils.IsError(err, `column "i" is being backfilled`) {
   741  					t.Error(err)
   742  				}
   743  				// TODO(vivek): Fix this error to return the same is being
   744  				// backfilled error.
   745  				_, err = sqlDB.Exec(`UPDATE t.test SET i = 'u' WHERE k = 'a'`)
   746  				if !testutils.IsError(err, `column "i" does not exist`) &&
   747  					!testutils.IsError(err, `column "i" is being backfilled`) {
   748  					t.Error(err)
   749  				}
   750  				_, err = sqlDB.Exec(`DELETE FROM t.test WHERE i < 'a'`)
   751  				if !testutils.IsError(err, `column "i" is being backfilled`) {
   752  					t.Error(err)
   753  				}
   754  
   755  				// Update a row without specifying  mutation column "i".
   756  				if useUpsert {
   757  					mTest.Exec(t, `UPSERT INTO t.test VALUES ('a', 'u')`)
   758  				} else {
   759  					mTest.Exec(t, `UPDATE t.test SET v = 'u' WHERE k = 'a'`)
   760  				}
   761  				// Make column "i" and index "foo" live.
   762  				mTest.makeMutationsActive()
   763  
   764  				if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   765  					// Mutation column "i" is not updated.
   766  					mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "u", "q"}, {"b", "y", "r"}, {"c", "x", "NULL"}})
   767  				} else {
   768  					// Mutation column "i" is set to its default value (NULL).
   769  					mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "u", "NULL"}, {"b", "y", "r"}, {"c", "x", "NULL"}})
   770  				}
   771  
   772  				if idxState == sqlbase.DescriptorMutation_DELETE_ONLY {
   773  					// Index entry for row "a" is deleted.
   774  					mTest.CheckQueryResults(t, indexQuery, [][]string{{"r"}})
   775  				} else {
   776  					// Index "foo" has NULL "i" value for row "a".
   777  					mTest.CheckQueryResults(t, indexQuery, [][]string{{"NULL"}, {"NULL"}, {"r"}})
   778  				}
   779  
   780  				// Add index "foo" as a mutation.
   781  				mTest.writeIndexMutation("foo", sqlbase.DescriptorMutation{State: idxState})
   782  				// Make column "i" a mutation.
   783  				mTest.writeColumnMutation("i", sqlbase.DescriptorMutation{State: state})
   784  
   785  				// Delete row "b".
   786  				mTest.Exec(t, `DELETE FROM t.test WHERE k = 'b'`)
   787  				// Make column "i" and index "foo" live.
   788  				mTest.makeMutationsActive()
   789  				// Row "b" is deleted.
   790  				if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   791  					mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "u", "q"}, {"c", "x", "NULL"}})
   792  				} else {
   793  					mTest.CheckQueryResults(t, starQuery, [][]string{{"a", "u", "NULL"}, {"c", "x", "NULL"}})
   794  				}
   795  
   796  				// numKVs is the number of expected key-values. We start with the number
   797  				// of non-NULL values above.
   798  				numKVs := 6
   799  				if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   800  					// In DELETE_ONLY case, the "q" value is not set to NULL above.
   801  					numKVs++
   802  				}
   803  
   804  				if idxState == sqlbase.DescriptorMutation_DELETE_ONLY {
   805  					// Index entry for row "a" is deleted.
   806  					mTest.CheckQueryResults(t, indexQuery, [][]string{})
   807  				} else {
   808  					// Index entry for row "a" is deleted.
   809  					if state == sqlbase.DescriptorMutation_DELETE_ONLY {
   810  						mTest.CheckQueryResults(t, indexQuery, [][]string{{"NULL"}, {"q"}})
   811  					} else {
   812  						mTest.CheckQueryResults(t, indexQuery, [][]string{{"NULL"}, {"NULL"}})
   813  					}
   814  					// We have two index values.
   815  					numKVs += 2
   816  				}
   817  
   818  				// Check that there are no hidden KV values for row "b", and column
   819  				// "i" for row "b" was deleted. Also check that the index values are
   820  				// all accounted for.
   821  				mTest.checkTableSize(numKVs)
   822  			}
   823  		}
   824  	}
   825  }
   826  
   827  // TestSchemaChangeCommandsWithPendingMutations tests how schema change
   828  // commands behave when they are referencing schema elements that are
   829  // mutations that are not yet live.
   830  func TestSchemaChangeCommandsWithPendingMutations(t *testing.T) {
   831  	defer leaktest.AfterTest(t)()
   832  	// The descriptor changes made must have an immediate effect
   833  	// so disable leases on tables.
   834  	defer lease.TestingDisableTableLeases()()
   835  	// Disable external processing of mutations.
   836  	params, _ := tests.CreateTestServerParams()
   837  	params.Knobs = base.TestingKnobs{
   838  		SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{
   839  			SchemaChangeJobNoOp: func() bool {
   840  				return true
   841  			},
   842  		},
   843  	}
   844  	server, sqlDB, kvDB := serverutils.StartServer(t, params)
   845  	defer server.Stopper().Stop(context.Background())
   846  
   847  	if _, err := sqlDB.Exec(`
   848  CREATE DATABASE t;
   849  CREATE TABLE t.test (a STRING PRIMARY KEY, b STRING, c STRING, INDEX foo (c));
   850  `); err != nil {
   851  		t.Fatal(err)
   852  	}
   853  
   854  	// Read table descriptor
   855  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   856  
   857  	mt := makeMutationTest(t, kvDB, sqlDB, tableDesc)
   858  
   859  	// Test CREATE INDEX in the presence of mutations.
   860  
   861  	// Add index DROP mutation "foo""
   862  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   863  	if _, err := sqlDB.Exec(`CREATE INDEX foo ON t.test (c)`); !testutils.IsError(err, `index "foo" being dropped, try again later`) {
   864  		t.Fatal(err)
   865  	}
   866  	// Make "foo" live.
   867  	mt.makeMutationsActive()
   868  
   869  	// "foo" is being added.
   870  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   871  	if _, err := sqlDB.Exec(`CREATE INDEX foo ON t.test (c)`); !testutils.IsError(err,
   872  		`relation "foo" already exists`) {
   873  		t.Fatal(err)
   874  	}
   875  	// Make "foo" live.
   876  	mt.makeMutationsActive()
   877  	// Add column DROP mutation "b"
   878  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   879  	if _, err := sqlDB.Exec(`CREATE INDEX bar ON t.test (b)`); !testutils.IsError(err, `column "b" does not exist`) {
   880  		t.Fatal(err)
   881  	}
   882  	// Make "b" live.
   883  	mt.makeMutationsActive()
   884  	// "b" is being added.
   885  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   886  	// An index referencing a column mutation that is being added
   887  	// is allowed to be added.
   888  	mt.Exec(t, `CREATE INDEX bar ON t.test (b)`)
   889  	// Make "b" live.
   890  	mt.makeMutationsActive()
   891  
   892  	// Test DROP INDEX in the presence of mutations.
   893  
   894  	// Add index DROP mutation "foo""
   895  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   896  	// Noop.
   897  	mt.Exec(t, `DROP INDEX t.test@foo`)
   898  	// Make "foo" live.
   899  	mt.makeMutationsActive()
   900  	// "foo" is being added.
   901  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   902  	if _, err := sqlDB.Exec(`DROP INDEX t.test@foo`); !testutils.IsError(err, `index "foo" in the middle of being added, try again later`) {
   903  		t.Fatal(err)
   904  	}
   905  	// Make "foo" live.
   906  	mt.makeMutationsActive()
   907  	// Test ALTER TABLE ADD/DROP column in the presence of mutations.
   908  
   909  	// Add column DROP mutation "b"
   910  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   911  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ADD b CHAR`); !testutils.IsError(err, `column "b" being dropped, try again later`) {
   912  		t.Fatal(err)
   913  	}
   914  	// Noop.
   915  	mt.Exec(t, `ALTER TABLE t.test DROP b`)
   916  	// Make "b" live.
   917  	mt.makeMutationsActive()
   918  	// "b" is being added.
   919  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   920  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ADD b CHAR`); !testutils.IsError(err,
   921  		`pq: duplicate: column "b" in the middle of being added, not yet public`) {
   922  		t.Fatal(err)
   923  	}
   924  	if _, err := sqlDB.Exec(`ALTER TABLE t.test DROP b`); !testutils.IsError(err, `column "b" in the middle of being added, try again later`) {
   925  		t.Fatal(err)
   926  	}
   927  	// Make "b" live.
   928  	mt.makeMutationsActive()
   929  
   930  	// Test ALTER TABLE ADD CONSTRAINT in the presence of mutations.
   931  
   932  	// Add index DROP mutation "foo""
   933  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   934  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ADD CONSTRAINT foo UNIQUE (c)`); !testutils.IsError(err, `index "foo" being dropped, try again later`) {
   935  		t.Fatal(err)
   936  	}
   937  	// Make "foo" live.
   938  	mt.makeMutationsActive()
   939  	// "foo" is being added.
   940  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   941  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ADD CONSTRAINT foo UNIQUE (c)`); !testutils.IsError(err,
   942  		`duplicate: index "foo" in the middle of being added, not yet public`) {
   943  		t.Fatal(err)
   944  	}
   945  	// Make "foo" live.
   946  	mt.makeMutationsActive()
   947  	// Add column mutation "b"
   948  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   949  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ADD CONSTRAINT bar UNIQUE (b)`); !testutils.IsError(err, `index "bar" contains unknown column "b"`) {
   950  		t.Fatal(err)
   951  	}
   952  	// Make "b" live.
   953  	mt.makeMutationsActive()
   954  	// "b" is being added.
   955  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   956  	// Noop.
   957  	mt.Exec(t, `ALTER TABLE t.test ADD CONSTRAINT bar UNIQUE (b)`)
   958  	// Make "b" live.
   959  	mt.makeMutationsActive()
   960  
   961  	// Test DROP CONSTRAINT in the presence of mutations.
   962  
   963  	// Add index mutation "foo""
   964  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
   965  	// Noop.
   966  	mt.Exec(t, `DROP INDEX t.test@foo`)
   967  	// Make "foo" live.
   968  	mt.makeMutationsActive()
   969  	// "foo" is being added.
   970  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
   971  	if _, err := sqlDB.Exec(`DROP INDEX t.test@foo`); !testutils.IsError(err, `index "foo" in the middle of being added, try again later`) {
   972  		t.Fatal(err)
   973  	}
   974  	// Make "foo" live.
   975  	mt.makeMutationsActive()
   976  
   977  	// Rename column/index, while index is under mutation.
   978  
   979  	// Add index mutation "foo""
   980  	mt.writeIndexMutation("foo", sqlbase.DescriptorMutation{})
   981  	mt.Exec(t, `ALTER INDEX t.test@foo RENAME to ufo`)
   982  	mt.Exec(t, `ALTER TABLE t.test RENAME COLUMN c TO d`)
   983  	// The mutation in the table descriptor has changed and we would like
   984  	// to update our copy to make it live.
   985  	mt.tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
   986  
   987  	// Make "ufo" live.
   988  	mt.makeMutationsActive()
   989  	// The index has been renamed to ufo, and the column to d.
   990  	mt.CheckQueryResults(t,
   991  		"SHOW INDEXES FROM t.test",
   992  		[][]string{
   993  			{"test", "primary", "false", "1", "a", "ASC", "false", "false"},
   994  			{"test", "ufo", "true", "1", "d", "ASC", "false", "false"},
   995  			{"test", "ufo", "true", "2", "a", "ASC", "false", "true"},
   996  		},
   997  	)
   998  
   999  	// Rename column under mutation works properly.
  1000  
  1001  	// Add column mutation "b".
  1002  	mt.writeColumnMutation("b", sqlbase.DescriptorMutation{})
  1003  	if _, err := sqlDB.Exec(`ALTER TABLE t.test RENAME COLUMN b TO e`); err != nil {
  1004  		mt.Fatal(err)
  1005  	}
  1006  
  1007  	// The mutation in the table descriptor has changed and we would like
  1008  	// to update our copy to make it live.
  1009  	mt.tableDesc = sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
  1010  
  1011  	// Make column "e" live.
  1012  	mt.makeMutationsActive()
  1013  	// Column b changed to d.
  1014  	mt.CheckQueryResults(t,
  1015  		"SHOW COLUMNS FROM t.test",
  1016  		[][]string{
  1017  			{"a", "STRING", "false", "NULL", "", "{primary,ufo}", "false"},
  1018  			{"e", "STRING", "true", "NULL", "", "{}", "false"},
  1019  			{"d", "STRING", "true", "NULL", "", "{ufo}", "false"},
  1020  		},
  1021  	)
  1022  
  1023  	// Try to change column defaults while column is under mutation.
  1024  	mt.writeColumnMutation("e", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_ADD})
  1025  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ALTER COLUMN e SET DEFAULT 'a'`); err != nil {
  1026  		t.Fatal(err)
  1027  	}
  1028  	mt.makeMutationsActive()
  1029  	mt.writeColumnMutation("e", sqlbase.DescriptorMutation{Direction: sqlbase.DescriptorMutation_DROP})
  1030  	if _, err := sqlDB.Exec(`ALTER TABLE t.test ALTER COLUMN e SET DEFAULT 'a'`); !testutils.IsError(
  1031  		err, `column "e" in the middle of being dropped`) {
  1032  		t.Fatal(err)
  1033  	}
  1034  	mt.makeMutationsActive()
  1035  }
  1036  
  1037  // TestTableMutationQueue tests that schema elements when added are
  1038  // assigned the correct start state and mutation id.
  1039  func TestTableMutationQueue(t *testing.T) {
  1040  	defer leaktest.AfterTest(t)()
  1041  	// Disable synchronous and asynchronous schema change processing so that
  1042  	// the mutations get queued up.
  1043  	params, _ := tests.CreateTestServerParams()
  1044  	params.Knobs = base.TestingKnobs{
  1045  		SQLSchemaChanger: &sql.SchemaChangerTestingKnobs{
  1046  			SchemaChangeJobNoOp: func() bool {
  1047  				return true
  1048  			},
  1049  		},
  1050  	}
  1051  	server, sqlDB, kvDB := serverutils.StartServer(t, params)
  1052  	defer server.Stopper().Stop(context.Background())
  1053  
  1054  	// Create a table with column i and an index on v and i.
  1055  	if _, err := sqlDB.Exec(`
  1056  CREATE DATABASE t;
  1057  CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR UNIQUE);
  1058  `); err != nil {
  1059  		t.Fatal(err)
  1060  	}
  1061  
  1062  	// Run some schema changes.
  1063  
  1064  	// This single command creates three columns and two indexes sharing the
  1065  	// same mutation ID.
  1066  	if _, err := sqlDB.Exec(
  1067  		`ALTER TABLE t.test ADD d INT UNIQUE, ADD e INT UNIQUE, ADD f INT`,
  1068  	); err != nil {
  1069  		t.Fatal(err)
  1070  	}
  1071  
  1072  	// This command creates two mutations sharing the same mutation ID.
  1073  	if _, err := sqlDB.Exec(
  1074  		`ALTER TABLE t.test ADD g INT, ADD CONSTRAINT idx_f UNIQUE (f)`,
  1075  	); err != nil {
  1076  		t.Fatal(err)
  1077  	}
  1078  
  1079  	// This command creates a single mutation.
  1080  	if _, err := sqlDB.Exec(`CREATE UNIQUE INDEX idx_g ON t.test (g)`); err != nil {
  1081  		t.Fatal(err)
  1082  	}
  1083  
  1084  	// This command created a drop mutation.
  1085  	if _, err := sqlDB.Exec(`ALTER TABLE t.test DROP v`); err != nil {
  1086  		t.Fatal(err)
  1087  	}
  1088  
  1089  	// read table descriptor
  1090  	tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "test")
  1091  
  1092  	expected := []struct {
  1093  		name  string
  1094  		id    sqlbase.MutationID
  1095  		state sqlbase.DescriptorMutation_State
  1096  	}{
  1097  		{"d", 1, sqlbase.DescriptorMutation_DELETE_ONLY},
  1098  		{"test_d_key", 1, sqlbase.DescriptorMutation_DELETE_ONLY},
  1099  		{"e", 1, sqlbase.DescriptorMutation_DELETE_ONLY},
  1100  		{"test_e_key", 1, sqlbase.DescriptorMutation_DELETE_ONLY},
  1101  		{"f", 1, sqlbase.DescriptorMutation_DELETE_ONLY},
  1102  		// Second schema change.
  1103  		{"g", 2, sqlbase.DescriptorMutation_DELETE_ONLY},
  1104  		{"idx_f", 2, sqlbase.DescriptorMutation_DELETE_ONLY},
  1105  		// Third.
  1106  		{"idx_g", 3, sqlbase.DescriptorMutation_DELETE_ONLY},
  1107  		// Drop mutations start off in the DELETE_AND_WRITE_ONLY state.
  1108  		// UNIQUE column deletion gets split into two mutations with the same ID.
  1109  		{"test_v_key", 4, sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY},
  1110  		{"v", 4, sqlbase.DescriptorMutation_DELETE_AND_WRITE_ONLY},
  1111  	}
  1112  
  1113  	if len(tableDesc.Mutations) != len(expected) {
  1114  		t.Fatalf("%d mutations, instead of expected %d", len(tableDesc.Mutations), len(expected))
  1115  	}
  1116  
  1117  	for i, m := range tableDesc.Mutations {
  1118  		name := expected[i].name
  1119  		if col := m.GetColumn(); col != nil {
  1120  			if col.Name != name {
  1121  				t.Errorf("%d entry: name %s, expected %s", i, col.Name, name)
  1122  			}
  1123  		}
  1124  		if idx := m.GetIndex(); idx != nil {
  1125  			if idx.Name != name {
  1126  				t.Errorf("%d entry: name %s, expected %s", i, idx.Name, name)
  1127  			}
  1128  		}
  1129  		if id := expected[i].id; m.MutationID != id {
  1130  			t.Errorf("%d entry: id %d, expected %d", i, m.MutationID, id)
  1131  		}
  1132  		if state := expected[i].state; m.State != state {
  1133  			t.Errorf("%d entry: state %s, expected %s", i, m.State, state)
  1134  		}
  1135  	}
  1136  }
  1137  
  1138  // TestAddingFKs checks the behavior of a table in the non-public `ADD` state.
  1139  // Being non-public, it should not be visible to clients, and is therefore
  1140  // assumed to be empty (e.g. by foreign key checks), since no one could have
  1141  // written to it yet.
  1142  func TestAddingFKs(t *testing.T) {
  1143  	defer leaktest.AfterTest(t)()
  1144  
  1145  	params, _ := tests.CreateTestServerParams()
  1146  	s, sqlDB, kvDB := serverutils.StartServer(t, params)
  1147  	defer s.Stopper().Stop(context.Background())
  1148  
  1149  	if _, err := sqlDB.Exec(`
  1150  		CREATE DATABASE t;
  1151  		CREATE TABLE t.products (id INT PRIMARY KEY);
  1152  		INSERT INTO t.products VALUES (1), (2);
  1153  		CREATE TABLE t.orders (id INT PRIMARY KEY, product INT REFERENCES t.products, INDEX (product));
  1154  	`); err != nil {
  1155  		t.Fatal(err)
  1156  	}
  1157  
  1158  	// Step the referencing table back to the ADD state.
  1159  	ordersDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "orders")
  1160  	ordersDesc.State = sqlbase.TableDescriptor_ADD
  1161  	ordersDesc.Version++
  1162  	if err := kvDB.Put(
  1163  		context.Background(),
  1164  		sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, ordersDesc.ID),
  1165  		sqlbase.WrapDescriptor(ordersDesc),
  1166  	); err != nil {
  1167  		t.Fatal(err)
  1168  	}
  1169  
  1170  	// Generally a referenced table needs to lookup referencing tables to check
  1171  	// FKs during delete operations, but referencing tables in the ADD state are
  1172  	// given special treatment.
  1173  	if _, err := sqlDB.Exec(`DELETE FROM t.products`); err != nil {
  1174  		t.Fatal(err)
  1175  	}
  1176  
  1177  	// Client should not see the orders table.
  1178  	if _, err := sqlDB.Exec(
  1179  		`SELECT * FROM t.orders`,
  1180  	); !testutils.IsError(err, `table is being added`) {
  1181  		t.Fatal(err)
  1182  	}
  1183  }