github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/structured_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 sqlbase
    12  
    13  import (
    14  	"context"
    15  	"encoding/json"
    16  	"fmt"
    17  	"reflect"
    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/roachpb"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    26  	"github.com/cockroachdb/cockroach/pkg/testutils"
    27  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    28  	"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
    29  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    30  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    31  )
    32  
    33  // Makes an IndexDescriptor with all columns being ascending.
    34  func makeIndexDescriptor(name string, columnNames []string) IndexDescriptor {
    35  	dirs := make([]IndexDescriptor_Direction, 0, len(columnNames))
    36  	for range columnNames {
    37  		dirs = append(dirs, IndexDescriptor_ASC)
    38  	}
    39  	idx := IndexDescriptor{
    40  		ID:               IndexID(0),
    41  		Name:             name,
    42  		ColumnNames:      columnNames,
    43  		ColumnDirections: dirs,
    44  	}
    45  	return idx
    46  }
    47  
    48  func TestAllocateIDs(t *testing.T) {
    49  	defer leaktest.AfterTest(t)()
    50  
    51  	desc := NewMutableCreatedTableDescriptor(TableDescriptor{
    52  		ParentID: keys.MinUserDescID,
    53  		ID:       keys.MinUserDescID + 1,
    54  		Name:     "foo",
    55  		Columns: []ColumnDescriptor{
    56  			{Name: "a", Type: types.Int},
    57  			{Name: "b", Type: types.Int},
    58  			{Name: "c", Type: types.Int},
    59  		},
    60  		PrimaryIndex: makeIndexDescriptor("c", []string{"a", "b"}),
    61  		Indexes: []IndexDescriptor{
    62  			makeIndexDescriptor("d", []string{"b", "a"}),
    63  			makeIndexDescriptor("e", []string{"b"}),
    64  			func() IndexDescriptor {
    65  				idx := makeIndexDescriptor("f", []string{"c"})
    66  				idx.EncodingType = PrimaryIndexEncoding
    67  				return idx
    68  			}(),
    69  		},
    70  		Privileges:    NewDefaultPrivilegeDescriptor(),
    71  		FormatVersion: FamilyFormatVersion,
    72  	})
    73  	if err := desc.AllocateIDs(); err != nil {
    74  		t.Fatal(err)
    75  	}
    76  
    77  	expected := NewMutableCreatedTableDescriptor(TableDescriptor{
    78  		ParentID: keys.MinUserDescID,
    79  		ID:       keys.MinUserDescID + 1,
    80  		Version:  1,
    81  		Name:     "foo",
    82  		Columns: []ColumnDescriptor{
    83  			{ID: 1, Name: "a", Type: types.Int},
    84  			{ID: 2, Name: "b", Type: types.Int},
    85  			{ID: 3, Name: "c", Type: types.Int},
    86  		},
    87  		Families: []ColumnFamilyDescriptor{
    88  			{
    89  				ID: 0, Name: "primary",
    90  				ColumnNames:     []string{"a", "b", "c"},
    91  				ColumnIDs:       []ColumnID{1, 2, 3},
    92  				DefaultColumnID: 3,
    93  			},
    94  		},
    95  		PrimaryIndex: IndexDescriptor{
    96  			ID: 1, Name: "c", ColumnIDs: []ColumnID{1, 2},
    97  			ColumnNames: []string{"a", "b"},
    98  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC,
    99  				IndexDescriptor_ASC}},
   100  		Indexes: []IndexDescriptor{
   101  			{ID: 2, Name: "d", ColumnIDs: []ColumnID{2, 1}, ColumnNames: []string{"b", "a"},
   102  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC,
   103  					IndexDescriptor_ASC}},
   104  			{ID: 3, Name: "e", ColumnIDs: []ColumnID{2}, ColumnNames: []string{"b"},
   105  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   106  				ExtraColumnIDs:   []ColumnID{1}},
   107  			{ID: 4, Name: "f", ColumnIDs: []ColumnID{3}, ColumnNames: []string{"c"},
   108  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   109  				EncodingType:     PrimaryIndexEncoding},
   110  		},
   111  		Privileges:     NewDefaultPrivilegeDescriptor(),
   112  		NextColumnID:   4,
   113  		NextFamilyID:   1,
   114  		NextIndexID:    5,
   115  		NextMutationID: 1,
   116  		FormatVersion:  FamilyFormatVersion,
   117  	})
   118  	if !reflect.DeepEqual(expected, desc) {
   119  		a, _ := json.MarshalIndent(expected, "", "  ")
   120  		b, _ := json.MarshalIndent(desc, "", "  ")
   121  		t.Fatalf("expected %s, but found %s", a, b)
   122  	}
   123  
   124  	if err := desc.AllocateIDs(); err != nil {
   125  		t.Fatal(err)
   126  	}
   127  	if !reflect.DeepEqual(expected, desc) {
   128  		a, _ := json.MarshalIndent(expected, "", "  ")
   129  		b, _ := json.MarshalIndent(desc, "", "  ")
   130  		t.Fatalf("expected %s, but found %s", a, b)
   131  	}
   132  }
   133  
   134  func TestValidateTableDesc(t *testing.T) {
   135  	defer leaktest.AfterTest(t)()
   136  
   137  	testData := []struct {
   138  		err  string
   139  		desc TableDescriptor
   140  	}{
   141  		{`empty table name`,
   142  			TableDescriptor{}},
   143  		{`invalid table ID 0`,
   144  			TableDescriptor{ID: 0, Name: "foo"}},
   145  		{`invalid parent ID 0`,
   146  			TableDescriptor{ID: 2, Name: "foo"}},
   147  		{`table "foo" is encoded using using version 0, but this client only supports version 2 and 3`,
   148  			TableDescriptor{ID: 2, ParentID: 1, Name: "foo"}},
   149  		{`table must contain at least 1 column`,
   150  			TableDescriptor{
   151  				ID:            2,
   152  				ParentID:      1,
   153  				Name:          "foo",
   154  				FormatVersion: FamilyFormatVersion,
   155  			}},
   156  		{`empty column name`,
   157  			TableDescriptor{
   158  				ID:            2,
   159  				ParentID:      1,
   160  				Name:          "foo",
   161  				FormatVersion: FamilyFormatVersion,
   162  				Columns: []ColumnDescriptor{
   163  					{ID: 0},
   164  				},
   165  				NextColumnID: 2,
   166  			}},
   167  		{`invalid column ID 0`,
   168  			TableDescriptor{
   169  				ID:            2,
   170  				ParentID:      1,
   171  				Name:          "foo",
   172  				FormatVersion: FamilyFormatVersion,
   173  				Columns: []ColumnDescriptor{
   174  					{ID: 0, Name: "bar"},
   175  				},
   176  				NextColumnID: 2,
   177  			}},
   178  		{`table must contain a primary key`,
   179  			TableDescriptor{
   180  				ID:            2,
   181  				ParentID:      1,
   182  				Name:          "foo",
   183  				FormatVersion: FamilyFormatVersion,
   184  				Columns: []ColumnDescriptor{
   185  					{ID: 1, Name: "bar"},
   186  				},
   187  				Families: []ColumnFamilyDescriptor{
   188  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   189  				},
   190  				NextColumnID: 2,
   191  				NextFamilyID: 1,
   192  			}},
   193  		{`duplicate column name: "bar"`,
   194  			TableDescriptor{
   195  				ID:            2,
   196  				ParentID:      1,
   197  				Name:          "foo",
   198  				FormatVersion: FamilyFormatVersion,
   199  				Columns: []ColumnDescriptor{
   200  					{ID: 1, Name: "bar"},
   201  					{ID: 1, Name: "bar"},
   202  				},
   203  				NextColumnID: 2,
   204  			}},
   205  		{`column "blah" duplicate ID of column "bar": 1`,
   206  			TableDescriptor{
   207  				ID:            2,
   208  				ParentID:      1,
   209  				Name:          "foo",
   210  				FormatVersion: FamilyFormatVersion,
   211  				Columns: []ColumnDescriptor{
   212  					{ID: 1, Name: "bar"},
   213  					{ID: 1, Name: "blah"},
   214  				},
   215  				NextColumnID: 2,
   216  			}},
   217  		{`at least 1 column family must be specified`,
   218  			TableDescriptor{
   219  				ID:            2,
   220  				ParentID:      1,
   221  				Name:          "foo",
   222  				FormatVersion: FamilyFormatVersion,
   223  				Columns: []ColumnDescriptor{
   224  					{ID: 1, Name: "bar"},
   225  				},
   226  				NextColumnID: 2,
   227  			}},
   228  		{`the 0th family must have ID 0`,
   229  			TableDescriptor{
   230  				ID:            2,
   231  				ParentID:      1,
   232  				Name:          "foo",
   233  				FormatVersion: FamilyFormatVersion,
   234  				Columns: []ColumnDescriptor{
   235  					{ID: 1, Name: "bar"},
   236  				},
   237  				Families: []ColumnFamilyDescriptor{
   238  					{ID: 1},
   239  				},
   240  				NextColumnID: 2,
   241  			}},
   242  		{`duplicate family name: "baz"`,
   243  			TableDescriptor{
   244  				ID:            2,
   245  				ParentID:      1,
   246  				Name:          "foo",
   247  				FormatVersion: FamilyFormatVersion,
   248  				Columns: []ColumnDescriptor{
   249  					{ID: 1, Name: "bar"},
   250  				},
   251  				Families: []ColumnFamilyDescriptor{
   252  					{ID: 0, Name: "baz"},
   253  					{ID: 1, Name: "baz"},
   254  				},
   255  				NextColumnID: 2,
   256  				NextFamilyID: 2,
   257  			}},
   258  		{`family "qux" duplicate ID of family "baz": 0`,
   259  			TableDescriptor{
   260  				ID:            2,
   261  				ParentID:      1,
   262  				Name:          "foo",
   263  				FormatVersion: FamilyFormatVersion,
   264  				Columns: []ColumnDescriptor{
   265  					{ID: 1, Name: "bar"},
   266  				},
   267  				Families: []ColumnFamilyDescriptor{
   268  					{ID: 0, Name: "baz"},
   269  					{ID: 0, Name: "qux"},
   270  				},
   271  				NextColumnID: 2,
   272  				NextFamilyID: 2,
   273  			}},
   274  		{`duplicate family name: "baz"`,
   275  			TableDescriptor{
   276  				ID:            2,
   277  				ParentID:      1,
   278  				Name:          "foo",
   279  				FormatVersion: FamilyFormatVersion,
   280  				Columns: []ColumnDescriptor{
   281  					{ID: 1, Name: "bar"},
   282  				},
   283  				Families: []ColumnFamilyDescriptor{
   284  					{ID: 0, Name: "baz"},
   285  					{ID: 3, Name: "baz"},
   286  				},
   287  				NextColumnID: 2,
   288  				NextFamilyID: 2,
   289  			}},
   290  		{`mismatched column ID size (1) and name size (0)`,
   291  			TableDescriptor{
   292  				ID:            2,
   293  				ParentID:      1,
   294  				Name:          "foo",
   295  				FormatVersion: FamilyFormatVersion,
   296  				Columns: []ColumnDescriptor{
   297  					{ID: 1, Name: "bar"},
   298  				},
   299  				Families: []ColumnFamilyDescriptor{
   300  					{ID: 0, Name: "baz", ColumnIDs: []ColumnID{1}},
   301  				},
   302  				NextColumnID: 2,
   303  				NextFamilyID: 1,
   304  			}},
   305  		{`family "baz" contains unknown column "2"`,
   306  			TableDescriptor{
   307  				ID:            2,
   308  				ParentID:      1,
   309  				Name:          "foo",
   310  				FormatVersion: FamilyFormatVersion,
   311  				Columns: []ColumnDescriptor{
   312  					{ID: 1, Name: "bar"},
   313  				},
   314  				Families: []ColumnFamilyDescriptor{
   315  					{ID: 0, Name: "baz", ColumnIDs: []ColumnID{2}, ColumnNames: []string{"bar"}},
   316  				},
   317  				NextColumnID: 2,
   318  				NextFamilyID: 1,
   319  			}},
   320  		{`family "baz" column 1 should have name "bar", but found name "qux"`,
   321  			TableDescriptor{
   322  				ID:            2,
   323  				ParentID:      1,
   324  				Name:          "foo",
   325  				FormatVersion: FamilyFormatVersion,
   326  				Columns: []ColumnDescriptor{
   327  					{ID: 1, Name: "bar"},
   328  				},
   329  				Families: []ColumnFamilyDescriptor{
   330  					{ID: 0, Name: "baz", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"qux"}},
   331  				},
   332  				NextColumnID: 2,
   333  				NextFamilyID: 1,
   334  			}},
   335  		{`column 1 is not in any column family`,
   336  			TableDescriptor{
   337  				ID:            2,
   338  				ParentID:      1,
   339  				Name:          "foo",
   340  				FormatVersion: FamilyFormatVersion,
   341  				Columns: []ColumnDescriptor{
   342  					{ID: 1, Name: "bar"},
   343  				},
   344  				Families: []ColumnFamilyDescriptor{
   345  					{ID: 0, Name: "baz"},
   346  				},
   347  				NextColumnID: 2,
   348  				NextFamilyID: 1,
   349  			}},
   350  		{`column 1 is in both family 0 and 1`,
   351  			TableDescriptor{
   352  				ID:            2,
   353  				ParentID:      1,
   354  				Name:          "foo",
   355  				FormatVersion: FamilyFormatVersion,
   356  				Columns: []ColumnDescriptor{
   357  					{ID: 1, Name: "bar"},
   358  				},
   359  				Families: []ColumnFamilyDescriptor{
   360  					{ID: 0, Name: "baz", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   361  					{ID: 1, Name: "qux", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   362  				},
   363  				NextColumnID: 2,
   364  				NextFamilyID: 2,
   365  			}},
   366  		{`table must contain a primary key`,
   367  			TableDescriptor{
   368  				ID:            2,
   369  				ParentID:      1,
   370  				Name:          "foo",
   371  				FormatVersion: FamilyFormatVersion,
   372  				Columns: []ColumnDescriptor{
   373  					{ID: 1, Name: "bar"},
   374  				},
   375  				Families: []ColumnFamilyDescriptor{
   376  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   377  				},
   378  				PrimaryIndex: IndexDescriptor{
   379  					ID:               0,
   380  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC}},
   381  				NextColumnID: 2,
   382  				NextFamilyID: 1,
   383  			}},
   384  		{`invalid index ID 0`,
   385  			TableDescriptor{
   386  				ID:            2,
   387  				ParentID:      1,
   388  				Name:          "foo",
   389  				FormatVersion: FamilyFormatVersion,
   390  				Columns: []ColumnDescriptor{
   391  					{ID: 1, Name: "bar"},
   392  				},
   393  				Families: []ColumnFamilyDescriptor{
   394  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   395  				},
   396  				PrimaryIndex: IndexDescriptor{ID: 0, Name: "bar",
   397  					ColumnIDs:        []ColumnID{0},
   398  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC}},
   399  				NextColumnID: 2,
   400  				NextFamilyID: 1,
   401  			}},
   402  		{`index "bar" must contain at least 1 column`,
   403  			TableDescriptor{
   404  				ID:            2,
   405  				ParentID:      1,
   406  				Name:          "foo",
   407  				FormatVersion: FamilyFormatVersion,
   408  				Columns: []ColumnDescriptor{
   409  					{ID: 1, Name: "bar"},
   410  				},
   411  				Families: []ColumnFamilyDescriptor{
   412  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   413  				},
   414  				PrimaryIndex: IndexDescriptor{
   415  					ID: 1, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"},
   416  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   417  				},
   418  				Indexes: []IndexDescriptor{
   419  					{ID: 2, Name: "bar"},
   420  				},
   421  				NextColumnID: 2,
   422  				NextFamilyID: 1,
   423  				NextIndexID:  3,
   424  			}},
   425  		{`mismatched column IDs (1) and names (0)`,
   426  			TableDescriptor{
   427  				ID:            2,
   428  				ParentID:      1,
   429  				Name:          "foo",
   430  				FormatVersion: FamilyFormatVersion,
   431  				Columns: []ColumnDescriptor{
   432  					{ID: 1, Name: "bar"},
   433  				},
   434  				Families: []ColumnFamilyDescriptor{
   435  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   436  				},
   437  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar", ColumnIDs: []ColumnID{1}},
   438  				NextColumnID: 2,
   439  				NextFamilyID: 1,
   440  				NextIndexID:  2,
   441  			}},
   442  		{`mismatched column IDs (1) and names (2)`,
   443  			TableDescriptor{
   444  				ID:            2,
   445  				ParentID:      1,
   446  				Name:          "foo",
   447  				FormatVersion: FamilyFormatVersion,
   448  				Columns: []ColumnDescriptor{
   449  					{ID: 1, Name: "bar"},
   450  					{ID: 2, Name: "blah"},
   451  				},
   452  				Families: []ColumnFamilyDescriptor{
   453  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1, 2}, ColumnNames: []string{"bar", "blah"}},
   454  				},
   455  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar",
   456  					ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar", "blah"},
   457  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   458  				},
   459  				NextColumnID: 3,
   460  				NextFamilyID: 1,
   461  				NextIndexID:  2,
   462  			}},
   463  		{`duplicate index name: "bar"`,
   464  			TableDescriptor{
   465  				ID:            2,
   466  				ParentID:      1,
   467  				Name:          "foo",
   468  				FormatVersion: FamilyFormatVersion,
   469  				Columns: []ColumnDescriptor{
   470  					{ID: 1, Name: "bar"},
   471  				},
   472  				Families: []ColumnFamilyDescriptor{
   473  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   474  				},
   475  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar",
   476  					ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"},
   477  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   478  				},
   479  				Indexes: []IndexDescriptor{
   480  					{ID: 2, Name: "bar", ColumnIDs: []ColumnID{1},
   481  						ColumnNames:      []string{"bar"},
   482  						ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   483  					},
   484  				},
   485  				NextColumnID: 2,
   486  				NextFamilyID: 1,
   487  				NextIndexID:  3,
   488  			}},
   489  		{`index "blah" duplicate ID of index "bar": 1`,
   490  			TableDescriptor{
   491  				ID:            2,
   492  				ParentID:      1,
   493  				Name:          "foo",
   494  				FormatVersion: FamilyFormatVersion,
   495  				Columns: []ColumnDescriptor{
   496  					{ID: 1, Name: "bar"},
   497  				},
   498  				Families: []ColumnFamilyDescriptor{
   499  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   500  				},
   501  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar", ColumnIDs: []ColumnID{1},
   502  					ColumnNames:      []string{"bar"},
   503  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   504  				},
   505  				Indexes: []IndexDescriptor{
   506  					{ID: 1, Name: "blah", ColumnIDs: []ColumnID{1},
   507  						ColumnNames:      []string{"bar"},
   508  						ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   509  					},
   510  				},
   511  				NextColumnID: 2,
   512  				NextFamilyID: 1,
   513  				NextIndexID:  2,
   514  			}},
   515  		{`index "bar" column "bar" should have ID 1, but found ID 2`,
   516  			TableDescriptor{
   517  				ID:            2,
   518  				ParentID:      1,
   519  				Name:          "foo",
   520  				FormatVersion: FamilyFormatVersion,
   521  				Columns: []ColumnDescriptor{
   522  					{ID: 1, Name: "bar"},
   523  				},
   524  				Families: []ColumnFamilyDescriptor{
   525  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   526  				},
   527  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar", ColumnIDs: []ColumnID{2},
   528  					ColumnNames:      []string{"bar"},
   529  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   530  				},
   531  				NextColumnID: 2,
   532  				NextFamilyID: 1,
   533  				NextIndexID:  2,
   534  			}},
   535  		{`index "bar" contains unknown column "blah"`,
   536  			TableDescriptor{
   537  				ID:            2,
   538  				ParentID:      1,
   539  				Name:          "foo",
   540  				FormatVersion: FamilyFormatVersion,
   541  				Columns: []ColumnDescriptor{
   542  					{ID: 1, Name: "bar"},
   543  				},
   544  				Families: []ColumnFamilyDescriptor{
   545  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   546  				},
   547  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar", ColumnIDs: []ColumnID{1},
   548  					ColumnNames:      []string{"blah"},
   549  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   550  				},
   551  				NextColumnID: 2,
   552  				NextFamilyID: 1,
   553  				NextIndexID:  2,
   554  			}},
   555  		{`mismatched column IDs (1) and directions (0)`,
   556  			TableDescriptor{
   557  				ID:            2,
   558  				ParentID:      1,
   559  				Name:          "foo",
   560  				FormatVersion: FamilyFormatVersion,
   561  				Columns: []ColumnDescriptor{
   562  					{ID: 1, Name: "bar"},
   563  				},
   564  				Families: []ColumnFamilyDescriptor{
   565  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   566  				},
   567  				PrimaryIndex: IndexDescriptor{ID: 1, Name: "bar", ColumnIDs: []ColumnID{1},
   568  					ColumnNames: []string{"blah"},
   569  				},
   570  				NextColumnID: 2,
   571  				NextFamilyID: 1,
   572  				NextIndexID:  2,
   573  			}},
   574  		{`at least one of LIST or RANGE partitioning must be used`,
   575  			// Verify that validatePartitioning is hooked up. The rest of these
   576  			// tests are in TestValidatePartitionion.
   577  			TableDescriptor{
   578  				ID:            2,
   579  				ParentID:      1,
   580  				Name:          "foo",
   581  				FormatVersion: FamilyFormatVersion,
   582  				Columns: []ColumnDescriptor{
   583  					{ID: 1, Name: "bar"},
   584  				},
   585  				Families: []ColumnFamilyDescriptor{
   586  					{ID: 0, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"}},
   587  				},
   588  				PrimaryIndex: IndexDescriptor{
   589  					ID: 1, Name: "primary", ColumnIDs: []ColumnID{1}, ColumnNames: []string{"bar"},
   590  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   591  					Partitioning: PartitioningDescriptor{
   592  						NumColumns: 1,
   593  					},
   594  				},
   595  				NextColumnID: 2,
   596  				NextFamilyID: 1,
   597  				NextIndexID:  3,
   598  			}},
   599  		{`index "foo_crdb_internal_bar_shard_5_bar_idx" refers to non-existent shard column "does not exist"`,
   600  			TableDescriptor{
   601  				ID:            2,
   602  				ParentID:      1,
   603  				Name:          "foo",
   604  				FormatVersion: FamilyFormatVersion,
   605  				Columns: []ColumnDescriptor{
   606  					{ID: 1, Name: "bar"},
   607  					{ID: 2, Name: "crdb_internal_bar_shard_5"},
   608  				},
   609  				Families: []ColumnFamilyDescriptor{
   610  					{ID: 0, Name: "primary",
   611  						ColumnIDs:   []ColumnID{1, 2},
   612  						ColumnNames: []string{"bar", "crdb_internal_bar_shard_5"},
   613  					},
   614  				},
   615  				PrimaryIndex: IndexDescriptor{
   616  					ID: 1, Name: "primary",
   617  					Unique:           true,
   618  					ColumnIDs:        []ColumnID{1},
   619  					ColumnNames:      []string{"bar"},
   620  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   621  					StoreColumnNames: []string{"crdb_internal_bar_shard_5"},
   622  					StoreColumnIDs:   []ColumnID{2},
   623  				},
   624  				Indexes: []IndexDescriptor{
   625  					{ID: 2, Name: "foo_crdb_internal_bar_shard_5_bar_idx",
   626  						ColumnIDs:        []ColumnID{2, 1},
   627  						ColumnNames:      []string{"crdb_internal_bar_shard_5", "bar"},
   628  						ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   629  						Sharded: ShardedDescriptor{
   630  							IsSharded:    true,
   631  							Name:         "does not exist",
   632  							ShardBuckets: 5,
   633  						},
   634  					},
   635  				},
   636  				NextColumnID: 3,
   637  				NextFamilyID: 1,
   638  				NextIndexID:  3,
   639  			}},
   640  	}
   641  	for i, d := range testData {
   642  		if err := d.desc.ValidateTable(); err == nil {
   643  			t.Errorf("%d: expected \"%s\", but found success: %+v", i, d.err, d.desc)
   644  		} else if d.err != err.Error() && "internal error: "+d.err != err.Error() {
   645  			t.Errorf("%d: expected \"%s\", but found \"%+v\"", i, d.err, err)
   646  		}
   647  	}
   648  }
   649  
   650  func TestValidateCrossTableReferences(t *testing.T) {
   651  	defer leaktest.AfterTest(t)()
   652  	ctx := context.Background()
   653  
   654  	s, _, kvDB := serverutils.StartServer(t, base.TestServerArgs{})
   655  	defer s.Stopper().Stop(ctx)
   656  
   657  	tests := []struct {
   658  		err        string
   659  		desc       TableDescriptor
   660  		otherDescs []TableDescriptor
   661  	}{
   662  		// Foreign keys
   663  		{
   664  			err: `invalid foreign key: missing table=52: descriptor not found`,
   665  			desc: TableDescriptor{
   666  				ID: 51,
   667  				OutboundFKs: []ForeignKeyConstraint{
   668  					{
   669  						Name:                "fk",
   670  						ReferencedTableID:   52,
   671  						ReferencedColumnIDs: []ColumnID{1},
   672  						OriginTableID:       51,
   673  						OriginColumnIDs:     []ColumnID{1},
   674  					},
   675  				},
   676  			},
   677  			otherDescs: nil,
   678  		},
   679  		{
   680  			err: `missing fk back reference "fk" to "foo" from "baz"`,
   681  			desc: TableDescriptor{
   682  				ID:   51,
   683  				Name: "foo",
   684  				OutboundFKs: []ForeignKeyConstraint{
   685  					{
   686  						Name:                "fk",
   687  						ReferencedTableID:   52,
   688  						ReferencedColumnIDs: []ColumnID{1},
   689  						OriginTableID:       51,
   690  						OriginColumnIDs:     []ColumnID{1},
   691  					},
   692  				},
   693  			},
   694  			otherDescs: []TableDescriptor{{
   695  				ID:   52,
   696  				Name: "baz",
   697  			}},
   698  		},
   699  		{
   700  			err: `invalid foreign key backreference: missing table=52: descriptor not found`,
   701  			desc: TableDescriptor{
   702  				ID: 51,
   703  				InboundFKs: []ForeignKeyConstraint{
   704  					{
   705  						Name:                "fk",
   706  						ReferencedTableID:   51,
   707  						ReferencedColumnIDs: []ColumnID{1},
   708  						OriginTableID:       52,
   709  						OriginColumnIDs:     []ColumnID{1},
   710  					},
   711  				},
   712  			},
   713  		},
   714  		{
   715  			err: `missing fk forward reference "fk" to "foo" from "baz"`,
   716  			desc: TableDescriptor{
   717  				ID:   51,
   718  				Name: "foo",
   719  				PrimaryIndex: IndexDescriptor{
   720  					ID:   1,
   721  					Name: "bar",
   722  				},
   723  				InboundFKs: []ForeignKeyConstraint{
   724  					{
   725  						Name:                "fk",
   726  						ReferencedTableID:   51,
   727  						ReferencedColumnIDs: []ColumnID{1},
   728  						OriginTableID:       52,
   729  						OriginColumnIDs:     []ColumnID{1},
   730  					},
   731  				},
   732  			},
   733  			otherDescs: []TableDescriptor{{
   734  				ID:   52,
   735  				Name: "baz",
   736  			}},
   737  		},
   738  
   739  		// Interleaves
   740  		{
   741  			err: `invalid interleave: missing table=52 index=2: descriptor not found`,
   742  			desc: TableDescriptor{
   743  				ID: 51,
   744  				PrimaryIndex: IndexDescriptor{
   745  					ID: 1,
   746  					Interleave: InterleaveDescriptor{Ancestors: []InterleaveDescriptor_Ancestor{
   747  						{TableID: 52, IndexID: 2},
   748  					}},
   749  				},
   750  			},
   751  			otherDescs: nil,
   752  		},
   753  		{
   754  			err: `invalid interleave: missing table=baz index=2: index-id "2" does not exist`,
   755  			desc: TableDescriptor{
   756  				ID: 51,
   757  				PrimaryIndex: IndexDescriptor{
   758  					ID: 1,
   759  					Interleave: InterleaveDescriptor{Ancestors: []InterleaveDescriptor_Ancestor{
   760  						{TableID: 52, IndexID: 2},
   761  					}},
   762  				},
   763  			},
   764  			otherDescs: []TableDescriptor{{
   765  				ID:   52,
   766  				Name: "baz",
   767  			}},
   768  		},
   769  		{
   770  			err: `missing interleave back reference to "foo"@"bar" from "baz"@"qux"`,
   771  			desc: TableDescriptor{
   772  				ID:   51,
   773  				Name: "foo",
   774  				PrimaryIndex: IndexDescriptor{
   775  					ID:   1,
   776  					Name: "bar",
   777  					Interleave: InterleaveDescriptor{Ancestors: []InterleaveDescriptor_Ancestor{
   778  						{TableID: 52, IndexID: 2},
   779  					}},
   780  				},
   781  			},
   782  			otherDescs: []TableDescriptor{{
   783  				ID:   52,
   784  				Name: "baz",
   785  				PrimaryIndex: IndexDescriptor{
   786  					ID:   2,
   787  					Name: "qux",
   788  				},
   789  			}},
   790  		},
   791  		{
   792  			err: `invalid interleave backreference table=52 index=2: descriptor not found`,
   793  			desc: TableDescriptor{
   794  				ID: 51,
   795  				PrimaryIndex: IndexDescriptor{
   796  					ID:            1,
   797  					InterleavedBy: []ForeignKeyReference{{Table: 52, Index: 2}},
   798  				},
   799  			},
   800  		},
   801  		{
   802  			err: `invalid interleave backreference table=baz index=2: index-id "2" does not exist`,
   803  			desc: TableDescriptor{
   804  				ID: 51,
   805  				PrimaryIndex: IndexDescriptor{
   806  					ID:            1,
   807  					InterleavedBy: []ForeignKeyReference{{Table: 52, Index: 2}},
   808  				},
   809  			},
   810  			otherDescs: []TableDescriptor{{
   811  				ID:   52,
   812  				Name: "baz",
   813  			}},
   814  		},
   815  		{
   816  			err: `broken interleave backward reference from "foo"@"bar" to "baz"@"qux"`,
   817  			desc: TableDescriptor{
   818  				ID:   51,
   819  				Name: "foo",
   820  				PrimaryIndex: IndexDescriptor{
   821  					ID:            1,
   822  					Name:          "bar",
   823  					InterleavedBy: []ForeignKeyReference{{Table: 52, Index: 2}},
   824  				},
   825  			},
   826  			otherDescs: []TableDescriptor{{
   827  				ID:   52,
   828  				Name: "baz",
   829  				PrimaryIndex: IndexDescriptor{
   830  					ID:   2,
   831  					Name: "qux",
   832  				},
   833  			}},
   834  		},
   835  	}
   836  
   837  	{
   838  		var v roachpb.Value
   839  		desc := &Descriptor{Union: &Descriptor_Database{}}
   840  		if err := v.SetProto(desc); err != nil {
   841  			t.Fatal(err)
   842  		}
   843  		if err := kvDB.Put(ctx, MakeDescMetadataKey(keys.SystemSQLCodec, 0), &v); err != nil {
   844  			t.Fatal(err)
   845  		}
   846  	}
   847  
   848  	for i, test := range tests {
   849  		for _, otherDesc := range test.otherDescs {
   850  			otherDesc.Privileges = NewDefaultPrivilegeDescriptor()
   851  			var v roachpb.Value
   852  			desc := &Descriptor{Union: &Descriptor_Table{Table: &otherDesc}}
   853  			if err := v.SetProto(desc); err != nil {
   854  				t.Fatal(err)
   855  			}
   856  			if err := kvDB.Put(ctx, MakeDescMetadataKey(keys.SystemSQLCodec, otherDesc.ID), &v); err != nil {
   857  				t.Fatal(err)
   858  			}
   859  		}
   860  		txn := kv.NewTxn(ctx, kvDB, s.NodeID())
   861  		if err := test.desc.validateCrossReferences(ctx, txn, keys.SystemSQLCodec); err == nil {
   862  			t.Errorf("%d: expected \"%s\", but found success: %+v", i, test.err, test.desc)
   863  		} else if test.err != err.Error() && "internal error: "+test.err != err.Error() {
   864  			t.Errorf("%d: expected \"%s\", but found \"%s\"", i, test.err, err.Error())
   865  		}
   866  		for _, otherDesc := range test.otherDescs {
   867  			if err := kvDB.Del(ctx, MakeDescMetadataKey(keys.SystemSQLCodec, otherDesc.ID)); err != nil {
   868  				t.Fatal(err)
   869  			}
   870  		}
   871  	}
   872  }
   873  
   874  func TestValidatePartitioning(t *testing.T) {
   875  	defer leaktest.AfterTest(t)()
   876  
   877  	tests := []struct {
   878  		err  string
   879  		desc TableDescriptor
   880  	}{
   881  		{"at least one of LIST or RANGE partitioning must be used",
   882  			TableDescriptor{
   883  				PrimaryIndex: IndexDescriptor{
   884  					Partitioning: PartitioningDescriptor{
   885  						NumColumns: 1,
   886  					},
   887  				},
   888  			},
   889  		},
   890  		{"PARTITION p1: must contain values",
   891  			TableDescriptor{
   892  				PrimaryIndex: IndexDescriptor{
   893  					Partitioning: PartitioningDescriptor{
   894  						NumColumns: 1,
   895  						List:       []PartitioningDescriptor_List{{Name: "p1"}},
   896  					},
   897  				},
   898  			},
   899  		},
   900  		{"not enough columns in index for this partitioning",
   901  			TableDescriptor{
   902  				PrimaryIndex: IndexDescriptor{
   903  					Partitioning: PartitioningDescriptor{
   904  						NumColumns: 1,
   905  						List:       []PartitioningDescriptor_List{{Name: "p1", Values: [][]byte{{}}}},
   906  					},
   907  				},
   908  			},
   909  		},
   910  		{"only one LIST or RANGE partitioning may used",
   911  			TableDescriptor{
   912  				PrimaryIndex: IndexDescriptor{
   913  					ColumnIDs:        []ColumnID{1},
   914  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   915  					Partitioning: PartitioningDescriptor{
   916  						NumColumns: 1,
   917  						List:       []PartitioningDescriptor_List{{}},
   918  						Range:      []PartitioningDescriptor_Range{{}},
   919  					},
   920  				},
   921  			},
   922  		},
   923  		{"PARTITION name must be non-empty",
   924  			TableDescriptor{
   925  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
   926  				PrimaryIndex: IndexDescriptor{
   927  					ColumnIDs:        []ColumnID{1},
   928  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   929  					Partitioning: PartitioningDescriptor{
   930  						NumColumns: 1,
   931  						List:       []PartitioningDescriptor_List{{}},
   932  					},
   933  				},
   934  			},
   935  		},
   936  		{"PARTITION p1: must contain values",
   937  			TableDescriptor{
   938  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
   939  				PrimaryIndex: IndexDescriptor{
   940  					ColumnIDs:        []ColumnID{1},
   941  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   942  					Partitioning: PartitioningDescriptor{
   943  						NumColumns: 1,
   944  						List:       []PartitioningDescriptor_List{{Name: "p1"}},
   945  					},
   946  				},
   947  			},
   948  		},
   949  		{"PARTITION p1: decoding: empty array",
   950  			TableDescriptor{
   951  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
   952  				PrimaryIndex: IndexDescriptor{
   953  					ColumnIDs:        []ColumnID{1},
   954  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   955  					Partitioning: PartitioningDescriptor{
   956  						NumColumns: 1,
   957  						List: []PartitioningDescriptor_List{{
   958  							Name: "p1", Values: [][]byte{{}},
   959  						}},
   960  					},
   961  				},
   962  			},
   963  		},
   964  		{"PARTITION p1: decoding: int64 varint decoding failed: 0",
   965  			TableDescriptor{
   966  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
   967  				PrimaryIndex: IndexDescriptor{
   968  					ColumnIDs:        []ColumnID{1},
   969  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   970  					Partitioning: PartitioningDescriptor{
   971  						NumColumns: 1,
   972  						List: []PartitioningDescriptor_List{
   973  							{Name: "p1", Values: [][]byte{{0x03}}},
   974  						},
   975  					},
   976  				},
   977  			},
   978  		},
   979  		{"PARTITION p1: superfluous data in encoded value",
   980  			TableDescriptor{
   981  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
   982  				PrimaryIndex: IndexDescriptor{
   983  					ColumnIDs:        []ColumnID{1},
   984  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   985  					Partitioning: PartitioningDescriptor{
   986  						NumColumns: 1,
   987  						List: []PartitioningDescriptor_List{
   988  							{Name: "p1", Values: [][]byte{{0x03, 0x02, 0x00}}},
   989  						},
   990  					},
   991  				},
   992  			},
   993  		},
   994  		{"partitions p1 and p2 overlap",
   995  			TableDescriptor{
   996  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
   997  				PrimaryIndex: IndexDescriptor{
   998  					ColumnIDs:        []ColumnID{1, 1},
   999  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1000  					Partitioning: PartitioningDescriptor{
  1001  						NumColumns: 1,
  1002  						Range: []PartitioningDescriptor_Range{
  1003  							{Name: "p1", FromInclusive: []byte{0x03, 0x02}, ToExclusive: []byte{0x03, 0x04}},
  1004  							{Name: "p2", FromInclusive: []byte{0x03, 0x02}, ToExclusive: []byte{0x03, 0x04}},
  1005  						},
  1006  					},
  1007  				},
  1008  			},
  1009  		},
  1010  		{"PARTITION p1: name must be unique",
  1011  			TableDescriptor{
  1012  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
  1013  				PrimaryIndex: IndexDescriptor{
  1014  					ColumnIDs:        []ColumnID{1},
  1015  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
  1016  					Partitioning: PartitioningDescriptor{
  1017  						NumColumns: 1,
  1018  						List: []PartitioningDescriptor_List{
  1019  							{Name: "p1", Values: [][]byte{{0x03, 0x02}}},
  1020  							{Name: "p1", Values: [][]byte{{0x03, 0x04}}},
  1021  						},
  1022  					},
  1023  				},
  1024  			},
  1025  		},
  1026  		{"not enough columns in index for this partitioning",
  1027  			TableDescriptor{
  1028  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
  1029  				PrimaryIndex: IndexDescriptor{
  1030  					ColumnIDs:        []ColumnID{1},
  1031  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
  1032  					Partitioning: PartitioningDescriptor{
  1033  						NumColumns: 1,
  1034  						List: []PartitioningDescriptor_List{{
  1035  							Name:   "p1",
  1036  							Values: [][]byte{{0x03, 0x02}},
  1037  							Subpartitioning: PartitioningDescriptor{
  1038  								NumColumns: 1,
  1039  								List:       []PartitioningDescriptor_List{{Name: "p1_1", Values: [][]byte{{}}}},
  1040  							},
  1041  						}},
  1042  					},
  1043  				},
  1044  			},
  1045  		},
  1046  		{"PARTITION p1: name must be unique",
  1047  			TableDescriptor{
  1048  				Columns: []ColumnDescriptor{{ID: 1, Type: types.Int}},
  1049  				PrimaryIndex: IndexDescriptor{
  1050  					ColumnIDs:        []ColumnID{1, 1},
  1051  					ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1052  					Partitioning: PartitioningDescriptor{
  1053  						NumColumns: 1,
  1054  						List: []PartitioningDescriptor_List{
  1055  							{Name: "p1", Values: [][]byte{{0x03, 0x02}}},
  1056  							{
  1057  								Name:   "p2",
  1058  								Values: [][]byte{{0x03, 0x04}},
  1059  								Subpartitioning: PartitioningDescriptor{
  1060  									NumColumns: 1,
  1061  									List: []PartitioningDescriptor_List{
  1062  										{Name: "p1", Values: [][]byte{{0x03, 0x02}}},
  1063  									},
  1064  								},
  1065  							},
  1066  						},
  1067  					},
  1068  				},
  1069  			},
  1070  		},
  1071  	}
  1072  	for i, test := range tests {
  1073  		err := test.desc.validatePartitioning()
  1074  		if !testutils.IsError(err, test.err) {
  1075  			t.Errorf(`%d: got "%v" expected "%v"`, i, err, test.err)
  1076  		}
  1077  	}
  1078  }
  1079  
  1080  func TestColumnTypeSQLString(t *testing.T) {
  1081  	defer leaktest.AfterTest(t)()
  1082  
  1083  	testData := []struct {
  1084  		colType     *types.T
  1085  		expectedSQL string
  1086  	}{
  1087  		{types.MakeBit(2), "BIT(2)"},
  1088  		{types.MakeVarBit(2), "VARBIT(2)"},
  1089  		{types.Int, "INT8"},
  1090  		{types.Float, "FLOAT8"},
  1091  		{types.Float4, "FLOAT4"},
  1092  		{types.Decimal, "DECIMAL"},
  1093  		{types.MakeDecimal(6, 0), "DECIMAL(6)"},
  1094  		{types.MakeDecimal(8, 7), "DECIMAL(8,7)"},
  1095  		{types.Date, "DATE"},
  1096  		{types.Timestamp, "TIMESTAMP"},
  1097  		{types.Interval, "INTERVAL"},
  1098  		{types.String, "STRING"},
  1099  		{types.MakeString(10), "STRING(10)"},
  1100  		{types.Bytes, "BYTES"},
  1101  	}
  1102  	for i, d := range testData {
  1103  		t.Run(d.colType.DebugString(), func(t *testing.T) {
  1104  			sql := d.colType.SQLString()
  1105  			if d.expectedSQL != sql {
  1106  				t.Errorf("%d: expected %s, but got %s", i, d.expectedSQL, sql)
  1107  			}
  1108  		})
  1109  	}
  1110  }
  1111  
  1112  func TestFitColumnToFamily(t *testing.T) {
  1113  	intEncodedSize := 10 // 1 byte tag + 9 bytes max varint encoded size
  1114  
  1115  	makeTestTableDescriptor := func(familyTypes [][]*types.T) *MutableTableDescriptor {
  1116  		nextColumnID := ColumnID(8)
  1117  		var desc TableDescriptor
  1118  		for _, fTypes := range familyTypes {
  1119  			var family ColumnFamilyDescriptor
  1120  			for _, t := range fTypes {
  1121  				desc.Columns = append(desc.Columns, ColumnDescriptor{
  1122  					ID:   nextColumnID,
  1123  					Type: t,
  1124  				})
  1125  				family.ColumnIDs = append(family.ColumnIDs, nextColumnID)
  1126  				nextColumnID++
  1127  			}
  1128  			desc.Families = append(desc.Families, family)
  1129  		}
  1130  		return NewMutableCreatedTableDescriptor(desc)
  1131  	}
  1132  
  1133  	emptyFamily := []*types.T{}
  1134  	partiallyFullFamily := []*types.T{
  1135  		types.Int,
  1136  		types.Bytes,
  1137  	}
  1138  	fullFamily := []*types.T{
  1139  		types.Bytes,
  1140  	}
  1141  	maxIntsInOneFamily := make([]*types.T, FamilyHeuristicTargetBytes/intEncodedSize)
  1142  	for i := range maxIntsInOneFamily {
  1143  		maxIntsInOneFamily[i] = types.Int
  1144  	}
  1145  
  1146  	tests := []struct {
  1147  		newCol           *types.T
  1148  		existingFamilies [][]*types.T
  1149  		colFits          bool
  1150  		idx              int // not applicable if colFits is false
  1151  	}{
  1152  		// Bounded size column.
  1153  		{colFits: true, idx: 0, newCol: types.Bool,
  1154  			existingFamilies: nil,
  1155  		},
  1156  		{colFits: true, idx: 0, newCol: types.Bool,
  1157  			existingFamilies: [][]*types.T{emptyFamily},
  1158  		},
  1159  		{colFits: true, idx: 0, newCol: types.Bool,
  1160  			existingFamilies: [][]*types.T{partiallyFullFamily},
  1161  		},
  1162  		{colFits: true, idx: 0, newCol: types.Bool,
  1163  			existingFamilies: [][]*types.T{fullFamily},
  1164  		},
  1165  		{colFits: true, idx: 0, newCol: types.Bool,
  1166  			existingFamilies: [][]*types.T{fullFamily, emptyFamily},
  1167  		},
  1168  
  1169  		// Unbounded size column.
  1170  		{colFits: true, idx: 0, newCol: types.Decimal,
  1171  			existingFamilies: [][]*types.T{emptyFamily},
  1172  		},
  1173  		{colFits: true, idx: 0, newCol: types.Decimal,
  1174  			existingFamilies: [][]*types.T{partiallyFullFamily},
  1175  		},
  1176  	}
  1177  	for i, test := range tests {
  1178  		desc := makeTestTableDescriptor(test.existingFamilies)
  1179  		idx, colFits := fitColumnToFamily(desc, ColumnDescriptor{Type: test.newCol})
  1180  		if colFits != test.colFits {
  1181  			if colFits {
  1182  				t.Errorf("%d: expected no fit for the column but got one", i)
  1183  			} else {
  1184  				t.Errorf("%d: expected fit for the column but didn't get one", i)
  1185  			}
  1186  			continue
  1187  		}
  1188  		if colFits && idx != test.idx {
  1189  			t.Errorf("%d: got a fit in family offset %d but expected offset %d", i, idx, test.idx)
  1190  		}
  1191  	}
  1192  }
  1193  
  1194  func TestMaybeUpgradeFormatVersion(t *testing.T) {
  1195  	tests := []struct {
  1196  		desc       TableDescriptor
  1197  		expUpgrade bool
  1198  		verify     func(int, TableDescriptor) // nil means no extra verification.
  1199  	}{
  1200  		{
  1201  			desc: TableDescriptor{
  1202  				FormatVersion: BaseFormatVersion,
  1203  				Columns: []ColumnDescriptor{
  1204  					{ID: 1, Name: "foo"},
  1205  				},
  1206  			},
  1207  			expUpgrade: true,
  1208  			verify: func(i int, desc TableDescriptor) {
  1209  				if len(desc.Families) == 0 {
  1210  					t.Errorf("%d: expected families to be set, but it was empty", i)
  1211  				}
  1212  			},
  1213  		},
  1214  		// Test that a version from the future is left alone.
  1215  		{
  1216  			desc: TableDescriptor{
  1217  				FormatVersion: InterleavedFormatVersion,
  1218  				Columns: []ColumnDescriptor{
  1219  					{ID: 1, Name: "foo"},
  1220  				},
  1221  			},
  1222  			expUpgrade: false,
  1223  			verify:     nil,
  1224  		},
  1225  	}
  1226  	for i, test := range tests {
  1227  		desc := test.desc
  1228  		upgraded := desc.maybeUpgradeFormatVersion()
  1229  		if upgraded != test.expUpgrade {
  1230  			t.Fatalf("%d: expected upgraded=%t, but got upgraded=%t", i, test.expUpgrade, upgraded)
  1231  		}
  1232  		if test.verify != nil {
  1233  			test.verify(i, desc)
  1234  		}
  1235  	}
  1236  }
  1237  
  1238  func TestUnvalidateConstraints(t *testing.T) {
  1239  	desc := NewMutableCreatedTableDescriptor(TableDescriptor{
  1240  		Name:     "test",
  1241  		ParentID: ID(1),
  1242  		Columns: []ColumnDescriptor{
  1243  			{Name: "a", Type: types.Int},
  1244  			{Name: "b", Type: types.Int},
  1245  			{Name: "c", Type: types.Int}},
  1246  		FormatVersion: FamilyFormatVersion,
  1247  		Indexes:       []IndexDescriptor{makeIndexDescriptor("d", []string{"b", "a"})},
  1248  		Privileges:    NewDefaultPrivilegeDescriptor(),
  1249  		OutboundFKs: []ForeignKeyConstraint{
  1250  			{
  1251  				Name:              "fk",
  1252  				ReferencedTableID: ID(1),
  1253  				Validity:          ConstraintValidity_Validated,
  1254  			},
  1255  		},
  1256  	})
  1257  	if err := desc.AllocateIDs(); err != nil {
  1258  		t.Fatal(err)
  1259  	}
  1260  	lookup := func(_ ID) (*TableDescriptor, error) {
  1261  		return desc.TableDesc(), nil
  1262  	}
  1263  
  1264  	before, err := desc.GetConstraintInfoWithLookup(lookup)
  1265  	if err != nil {
  1266  		t.Fatal(err)
  1267  	}
  1268  	if c, ok := before["fk"]; !ok || c.Unvalidated {
  1269  		t.Fatalf("expected to find a validated constraint fk before, found %v", c)
  1270  	}
  1271  	desc.InvalidateFKConstraints()
  1272  
  1273  	after, err := desc.GetConstraintInfoWithLookup(lookup)
  1274  	if err != nil {
  1275  		t.Fatal(err)
  1276  	}
  1277  	if c, ok := after["fk"]; !ok || !c.Unvalidated {
  1278  		t.Fatalf("expected to find an unvalidated constraint fk before, found %v", c)
  1279  	}
  1280  }
  1281  
  1282  func TestKeysPerRow(t *testing.T) {
  1283  	defer leaktest.AfterTest(t)()
  1284  
  1285  	// TODO(dan): This server is only used to turn a CREATE TABLE statement into
  1286  	// a TableDescriptor. It should be possible to move MakeTableDesc into
  1287  	// sqlbase. If/when that happens, use it here instead of this server.
  1288  	s, conn, _ := serverutils.StartServer(t, base.TestServerArgs{})
  1289  	defer s.Stopper().Stop(context.Background())
  1290  	if _, err := conn.Exec(`CREATE DATABASE d`); err != nil {
  1291  		t.Fatalf("%+v", err)
  1292  	}
  1293  
  1294  	tests := []struct {
  1295  		createTable string
  1296  		indexID     IndexID
  1297  		expected    int
  1298  	}{
  1299  		{"(a INT PRIMARY KEY, b INT, INDEX (b))", 1, 1},                                     // Primary index
  1300  		{"(a INT PRIMARY KEY, b INT, INDEX (b))", 2, 1},                                     // 'b' index
  1301  		{"(a INT PRIMARY KEY, b INT, FAMILY (a), FAMILY (b), INDEX (b))", 1, 2},             // Primary index
  1302  		{"(a INT PRIMARY KEY, b INT, FAMILY (a), FAMILY (b), INDEX (b))", 2, 1},             // 'b' index
  1303  		{"(a INT PRIMARY KEY, b INT, FAMILY (a), FAMILY (b), INDEX (a) STORING (b))", 2, 2}, // 'a' index
  1304  	}
  1305  
  1306  	for i, test := range tests {
  1307  		t.Run(fmt.Sprintf("%s - %d", test.createTable, test.indexID), func(t *testing.T) {
  1308  			sqlDB := sqlutils.MakeSQLRunner(conn)
  1309  			tableName := fmt.Sprintf("t%d", i)
  1310  			sqlDB.Exec(t, fmt.Sprintf(`CREATE TABLE d.%s %s`, tableName, test.createTable))
  1311  
  1312  			var descBytes []byte
  1313  			// Grab the most recently created descriptor.
  1314  			row := sqlDB.QueryRow(t,
  1315  				`SELECT descriptor FROM system.descriptor ORDER BY id DESC LIMIT 1`)
  1316  			row.Scan(&descBytes)
  1317  			var desc Descriptor
  1318  			if err := protoutil.Unmarshal(descBytes, &desc); err != nil {
  1319  				t.Fatalf("%+v", err)
  1320  			}
  1321  
  1322  			keys, err := desc.GetTable().KeysPerRow(test.indexID)
  1323  			if err != nil {
  1324  				t.Fatal(err)
  1325  			}
  1326  			if test.expected != keys {
  1327  				t.Errorf("expected %d keys got %d", test.expected, keys)
  1328  			}
  1329  		})
  1330  	}
  1331  }
  1332  
  1333  func TestColumnNeedsBackfill(t *testing.T) {
  1334  	// Define variable strings here such that we can pass their address below.
  1335  	null := "NULL"
  1336  	four := "4:::INT8"
  1337  	// Create Column Descriptors that reflect the definition of a column with a
  1338  	// default value of NULL that was set implicitly, one that was set explicitly,
  1339  	// and one that has an INT default value, respectively.
  1340  	implicitNull := &ColumnDescriptor{Name: "im", ID: 2, Type: types.Int, DefaultExpr: nil, Nullable: true, ComputeExpr: nil}
  1341  	explicitNull := &ColumnDescriptor{Name: "ex", ID: 3, Type: types.Int, DefaultExpr: &null, Nullable: true, ComputeExpr: nil}
  1342  	defaultNotNull := &ColumnDescriptor{Name: "four", ID: 4, Type: types.Int, DefaultExpr: &four, Nullable: true, ComputeExpr: nil}
  1343  	// Verify that a backfill doesn't occur according to the ColumnNeedsBackfill
  1344  	// function for the default NULL values, and that it does occur for an INT
  1345  	// default value.
  1346  	if ColumnNeedsBackfill(implicitNull) != false {
  1347  		t.Fatal("Expected implicit SET DEFAULT NULL to not require a backfill," +
  1348  			" ColumnNeedsBackfill states that it does.")
  1349  	}
  1350  	if ColumnNeedsBackfill(explicitNull) != false {
  1351  		t.Fatal("Expected explicit SET DEFAULT NULL to not require a backfill," +
  1352  			" ColumnNeedsBackfill states that it does.")
  1353  	}
  1354  	if ColumnNeedsBackfill(defaultNotNull) != true {
  1355  		t.Fatal("Expected explicit SET DEFAULT NULL to require a backfill," +
  1356  			" ColumnNeedsBackfill states that it does not.")
  1357  	}
  1358  }
  1359  
  1360  func TestDefaultExprNil(t *testing.T) {
  1361  	s, conn, _ := serverutils.StartServer(t, base.TestServerArgs{})
  1362  	defer s.Stopper().Stop(context.Background())
  1363  	if _, err := conn.Exec(`CREATE DATABASE t`); err != nil {
  1364  		t.Fatalf("%+v", err)
  1365  	}
  1366  	t.Run(fmt.Sprintf("%s - %d", "(a INT PRIMARY KEY)", 1), func(t *testing.T) {
  1367  		sqlDB := sqlutils.MakeSQLRunner(conn)
  1368  		// Execute SQL commands with both implicit and explicit setting of the
  1369  		// default expression.
  1370  		sqlDB.Exec(t, `CREATE TABLE t (a INT PRIMARY KEY)`)
  1371  		sqlDB.Exec(t, `INSERT INTO t (a) VALUES (1), (2)`)
  1372  		sqlDB.Exec(t, `ALTER TABLE t ADD COLUMN b INT NULL`)
  1373  		sqlDB.Exec(t, `INSERT INTO t (a) VALUES (3)`)
  1374  		sqlDB.Exec(t, `ALTER TABLE t ADD COLUMN c INT DEFAULT NULL`)
  1375  
  1376  		var descBytes []byte
  1377  		// Grab the most recently created descriptor.
  1378  		row := sqlDB.QueryRow(t,
  1379  			`SELECT descriptor FROM system.descriptor ORDER BY id DESC LIMIT 1`)
  1380  		row.Scan(&descBytes)
  1381  		var desc Descriptor
  1382  		if err := protoutil.Unmarshal(descBytes, &desc); err != nil {
  1383  			t.Fatalf("%+v", err)
  1384  		}
  1385  		// Test and verify that the default expressions of the column descriptors
  1386  		// are all nil.
  1387  		for _, col := range desc.GetTable().Columns {
  1388  			if col.DefaultExpr != nil {
  1389  				t.Errorf("expected Column Default Expression to be 'nil', got %s instead.", *col.DefaultExpr)
  1390  			}
  1391  		}
  1392  	})
  1393  }
  1394  
  1395  func TestSQLString(t *testing.T) {
  1396  	colNames := []string{"derp", "foo"}
  1397  	indexName := "idx"
  1398  	tableName := tree.MakeTableName("DB", "t1")
  1399  	tableName.ExplicitCatalog = false
  1400  	tableName.ExplicitSchema = false
  1401  	index := IndexDescriptor{Name: indexName,
  1402  		ID:               0x0,
  1403  		Unique:           false,
  1404  		ColumnNames:      colNames,
  1405  		ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1406  	}
  1407  	expected := fmt.Sprintf("INDEX %s ON t1 (%s ASC, %s ASC)", indexName, colNames[0], colNames[1])
  1408  	if got := index.SQLString(&tableName); got != expected {
  1409  		t.Errorf("Expected '%s', but got '%s'", expected, got)
  1410  	}
  1411  	expected = fmt.Sprintf("INDEX %s (%s ASC, %s ASC)", indexName, colNames[0], colNames[1])
  1412  	if got := index.SQLString(&AnonymousTable); got != expected {
  1413  		t.Errorf("Expected '%s', but got '%s'", expected, got)
  1414  	}
  1415  }
  1416  
  1417  func TestLogicalColumnID(t *testing.T) {
  1418  	tests := []struct {
  1419  		desc     TableDescriptor
  1420  		expected ColumnID
  1421  	}{
  1422  		{TableDescriptor{Columns: []ColumnDescriptor{{ID: 1, LogicalColumnID: 1}}}, 1},
  1423  		// If LogicalColumnID is not explicitly set, it should be lazy loaded as ID.
  1424  		{TableDescriptor{Columns: []ColumnDescriptor{{ID: 2}}}, 2},
  1425  	}
  1426  
  1427  	for i := range tests {
  1428  		actual := tests[i].desc.Columns[0].GetLogicalColumnID()
  1429  		expected := tests[i].expected
  1430  
  1431  		if expected != actual {
  1432  			t.Fatalf("Expected LogicalColumnID to be %d, got %d.", expected, actual)
  1433  		}
  1434  	}
  1435  
  1436  }