github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/message/result_rows_test.go (about)

     1  // Copyright 2020 DataStax
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package message
    16  
    17  import (
    18  	"bytes"
    19  	"testing"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  
    23  	"github.com/datastax/go-cassandra-native-protocol/datatype"
    24  	"github.com/datastax/go-cassandra-native-protocol/primitive"
    25  )
    26  
    27  func TestRowsResult_DeepCopy(t *testing.T) {
    28  	msg := &RowsResult{
    29  		Metadata: &RowsMetadata{
    30  			ColumnCount:          1,
    31  			PagingState:          nil,
    32  			NewResultMetadataId:  nil,
    33  			ContinuousPageNumber: 1,
    34  			LastContinuousPage:   false,
    35  			Columns: []*ColumnMetadata{
    36  				{
    37  					Keyspace: "ks1",
    38  					Table:    "tb1",
    39  					Name:     "c1",
    40  					Index:    0,
    41  					Type:     datatype.Ascii,
    42  				},
    43  			},
    44  		},
    45  		Data: RowSet{
    46  			{
    47  				{0x12, 0x23},
    48  			},
    49  			{
    50  				{0x44, 0x55},
    51  			},
    52  		},
    53  	}
    54  
    55  	cloned := msg.DeepCopy()
    56  	assert.Equal(t, msg, cloned)
    57  
    58  	cloned.Metadata = &RowsMetadata{
    59  		ColumnCount:          1,
    60  		PagingState:          []byte{0x22},
    61  		NewResultMetadataId:  []byte{0x33},
    62  		ContinuousPageNumber: 3,
    63  		LastContinuousPage:   true,
    64  		Columns: []*ColumnMetadata{
    65  			{
    66  				Keyspace: "ks2",
    67  				Table:    "tb2",
    68  				Name:     "c2",
    69  				Index:    0,
    70  				Type:     datatype.Float,
    71  			},
    72  			{
    73  				Keyspace: "ks2",
    74  				Table:    "tb2",
    75  				Name:     "c3",
    76  				Index:    1,
    77  				Type:     datatype.Uuid,
    78  			},
    79  		},
    80  	}
    81  	cloned.Data = RowSet{
    82  		{
    83  			{0x52, 0x63},
    84  		},
    85  	}
    86  
    87  	assert.NotEqual(t, msg, cloned)
    88  
    89  	assert.EqualValues(t, 1, msg.Metadata.ColumnCount)
    90  	assert.Nil(t, msg.Metadata.PagingState)
    91  	assert.Nil(t, msg.Metadata.NewResultMetadataId)
    92  	assert.EqualValues(t, 1, msg.Metadata.ContinuousPageNumber)
    93  	assert.False(t, msg.Metadata.LastContinuousPage)
    94  	assert.Equal(t, "ks1", msg.Metadata.Columns[0].Keyspace)
    95  	assert.Equal(t, "tb1", msg.Metadata.Columns[0].Table)
    96  	assert.Equal(t, "c1", msg.Metadata.Columns[0].Name)
    97  	assert.EqualValues(t, 0, msg.Metadata.Columns[0].Index)
    98  	assert.Equal(t, datatype.Ascii, msg.Metadata.Columns[0].Type)
    99  	assert.Equal(t, RowSet{{{0x12, 0x23}}, {{0x44, 0x55}}}, msg.Data)
   100  
   101  	assert.EqualValues(t, 1, cloned.Metadata.ColumnCount)
   102  	assert.Equal(t, []byte{0x22}, cloned.Metadata.PagingState)
   103  	assert.Equal(t, []byte{0x33}, cloned.Metadata.NewResultMetadataId)
   104  	assert.EqualValues(t, 3, cloned.Metadata.ContinuousPageNumber)
   105  	assert.True(t, cloned.Metadata.LastContinuousPage)
   106  	assert.Equal(t, "ks2", cloned.Metadata.Columns[0].Keyspace)
   107  	assert.Equal(t, "tb2", cloned.Metadata.Columns[0].Table)
   108  	assert.Equal(t, "c2", cloned.Metadata.Columns[0].Name)
   109  	assert.EqualValues(t, 0, cloned.Metadata.Columns[0].Index)
   110  	assert.Equal(t, datatype.Float, cloned.Metadata.Columns[0].Type)
   111  	assert.Equal(t, "ks2", cloned.Metadata.Columns[1].Keyspace)
   112  	assert.Equal(t, "tb2", cloned.Metadata.Columns[1].Table)
   113  	assert.Equal(t, "c3", cloned.Metadata.Columns[1].Name)
   114  	assert.EqualValues(t, 1, cloned.Metadata.Columns[1].Index)
   115  	assert.Equal(t, datatype.Uuid, cloned.Metadata.Columns[1].Type)
   116  	assert.Equal(t, RowSet{{{0x52, 0x63}}}, cloned.Data)
   117  }
   118  
   119  func TestResultCodec_Encode_Rows(test *testing.T) {
   120  	row1 := Row{
   121  		Column{0, 0, 0, 1},    // int = 1
   122  		Column{h, e, l, l, o}, // varchar = "hello"
   123  	}
   124  	row2 := Row{
   125  		Column{0, 0, 0, 2},    // int = 2
   126  		Column{w, o, r, l, d}, // varchar = "world"
   127  	}
   128  	spec1 := &ColumnMetadata{
   129  		Keyspace: "ks1",
   130  		Table:    "table1",
   131  		Name:     "col1",
   132  		Index:    0,
   133  		Type:     datatype.Int,
   134  	}
   135  	spec2 := &ColumnMetadata{
   136  		Keyspace: "ks1",
   137  		Table:    "table1",
   138  		Name:     "col2",
   139  		Index:    0,
   140  		Type:     datatype.Varchar,
   141  	}
   142  	spec3 := &ColumnMetadata{
   143  		Keyspace: "ks1",
   144  		Table:    "table2",
   145  		Name:     "col2",
   146  		Index:    0,
   147  		Type:     datatype.Varchar,
   148  	}
   149  	codec := &resultCodec{}
   150  	// versions < 5
   151  	for _, version := range primitive.SupportedProtocolVersionsLesserThan(primitive.ProtocolVersion5) {
   152  		test.Run(version.String(), func(test *testing.T) {
   153  			tests := []encodeTestCase{
   154  				{
   155  					"rows result without column metadata",
   156  					&RowsResult{
   157  						Metadata: &RowsMetadata{
   158  							ColumnCount: 2,
   159  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   160  						},
   161  						Data: RowSet{row1, row2},
   162  					},
   163  					[]byte{
   164  						0, 0, 0, 2, // result type
   165  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
   166  						0, 0, 0, 2, // column count
   167  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   168  						0, 0, 0, 2, // rows count
   169  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   170  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   171  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   172  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   173  					},
   174  					nil,
   175  				},
   176  				{
   177  					"rows result with column metadata",
   178  					&RowsResult{
   179  						Metadata: &RowsMetadata{
   180  							ColumnCount: 2,
   181  							Columns:     []*ColumnMetadata{spec1, spec2},
   182  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   183  						},
   184  						Data: RowSet{row1, row2},
   185  					},
   186  					[]byte{
   187  						0, 0, 0, 2, // result type
   188  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
   189  						0, 0, 0, 2, // column count
   190  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   191  						0, 3, k, s, _1, // global ks
   192  						0, 6, t, a, b, l, e, _1, // global table
   193  						0, 4, c, o, l, _1, // col1 name
   194  						0, 9, // col1 type
   195  						0, 4, c, o, l, _2, // col2 name
   196  						0, 13, // col2 type
   197  						0, 0, 0, 2, // rows count
   198  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   199  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   200  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   201  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   202  					},
   203  					nil,
   204  				},
   205  				{
   206  					"rows result with column metadata no global table spec last page",
   207  					&RowsResult{
   208  						Metadata: &RowsMetadata{
   209  							ColumnCount: 2,
   210  							Columns:     []*ColumnMetadata{spec1, spec3},
   211  						},
   212  						Data: RowSet{row1, row2},
   213  					},
   214  					[]byte{
   215  						0, 0, 0, 2, // result type
   216  						0, 0, 0, 0, // flags
   217  						0, 0, 0, 2, // column count
   218  						0, 3, k, s, _1, // col1 ks
   219  						0, 6, t, a, b, l, e, _1, // col1 table
   220  						0, 4, c, o, l, _1, // col1 name
   221  						0, 9, // col1 type
   222  						0, 3, k, s, _1, // col2 ks
   223  						0, 6, t, a, b, l, e, _2, // col2 table
   224  						0, 4, c, o, l, _2, // col2 name
   225  						0, 13, // col2 type
   226  						0, 0, 0, 2, // rows count
   227  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   228  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   229  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   230  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   231  					},
   232  					nil,
   233  				},
   234  			}
   235  			for _, tt := range tests {
   236  				test.Run(tt.name, func(t *testing.T) {
   237  					dest := &bytes.Buffer{}
   238  					err := codec.Encode(tt.input, dest, version)
   239  					assert.Equal(t, tt.expected, dest.Bytes())
   240  					assert.Equal(t, tt.err, err)
   241  				})
   242  			}
   243  		})
   244  	}
   245  	// version = 5
   246  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersion5} {
   247  		test.Run(version.String(), func(test *testing.T) {
   248  			tests := []encodeTestCase{
   249  				{
   250  					"rows result without column metadata",
   251  					&RowsResult{
   252  						Metadata: &RowsMetadata{
   253  							ColumnCount: 2,
   254  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   255  						},
   256  						Data: RowSet{row1, row2},
   257  					},
   258  					[]byte{
   259  						0, 0, 0, 2, // result type
   260  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
   261  						0, 0, 0, 2, // column count
   262  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   263  						0, 0, 0, 2, // rows count
   264  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   265  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   266  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   267  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   268  					},
   269  					nil,
   270  				},
   271  				{
   272  					"rows result with column metadata",
   273  					&RowsResult{
   274  						Metadata: &RowsMetadata{
   275  							ColumnCount: 2,
   276  							Columns:     []*ColumnMetadata{spec1, spec2},
   277  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   278  						},
   279  						Data: RowSet{row1, row2},
   280  					},
   281  					[]byte{
   282  						0, 0, 0, 2, // result type
   283  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
   284  						0, 0, 0, 2, // column count
   285  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   286  						0, 3, k, s, _1, // global ks
   287  						0, 6, t, a, b, l, e, _1, // global table
   288  						0, 4, c, o, l, _1, // col1 name
   289  						0, 9, // col1 type
   290  						0, 4, c, o, l, _2, // col2 name
   291  						0, 13, // col2 type
   292  						0, 0, 0, 2, // rows count
   293  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   294  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   295  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   296  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   297  					},
   298  					nil,
   299  				},
   300  				{
   301  					"rows result with column metadata no global table spec last page",
   302  					&RowsResult{
   303  						Metadata: &RowsMetadata{
   304  							ColumnCount: 2,
   305  							Columns:     []*ColumnMetadata{spec1, spec3},
   306  						},
   307  						Data: RowSet{row1, row2},
   308  					},
   309  					[]byte{
   310  						0, 0, 0, 2, // result type
   311  						0, 0, 0, 0, // flags
   312  						0, 0, 0, 2, // column count
   313  						0, 3, k, s, _1, // col1 ks
   314  						0, 6, t, a, b, l, e, _1, // col1 table
   315  						0, 4, c, o, l, _1, // col1 name
   316  						0, 9, // col1 type
   317  						0, 3, k, s, _1, // col2 ks
   318  						0, 6, t, a, b, l, e, _2, // col2 table
   319  						0, 4, c, o, l, _2, // col2 name
   320  						0, 13, // col2 type
   321  						0, 0, 0, 2, // rows count
   322  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   323  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   324  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   325  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   326  					},
   327  					nil,
   328  				},
   329  				{
   330  					"rows result with column metadata and new result metadata id",
   331  					&RowsResult{
   332  						Metadata: &RowsMetadata{
   333  							ColumnCount:         2,
   334  							Columns:             []*ColumnMetadata{spec1, spec2},
   335  							NewResultMetadataId: []byte{1, 2, 3, 4},
   336  							PagingState:         []byte{0xca, 0xfe, 0xba, 0xbe},
   337  						},
   338  						Data: RowSet{row1, row2},
   339  					},
   340  					[]byte{
   341  						0, 0, 0, 2, // result type
   342  						0, 0, 0, 11, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES | METADATA_CHANGED)
   343  						0, 0, 0, 2, // column count
   344  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   345  						0, 4, 1, 2, 3, 4, // new result metadata id
   346  						0, 3, k, s, _1, // global ks
   347  						0, 6, t, a, b, l, e, _1, // global table
   348  						0, 4, c, o, l, _1, // col1 name
   349  						0, 9, // col1 type
   350  						0, 4, c, o, l, _2, // col2 name
   351  						0, 13, // col2 type
   352  						0, 0, 0, 2, // rows count
   353  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   354  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   355  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   356  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   357  					},
   358  					nil,
   359  				},
   360  			}
   361  			for _, tt := range tests {
   362  				test.Run(tt.name, func(t *testing.T) {
   363  					dest := &bytes.Buffer{}
   364  					err := codec.Encode(tt.input, dest, version)
   365  					assert.Equal(t, tt.expected, dest.Bytes())
   366  					assert.Equal(t, tt.err, err)
   367  				})
   368  			}
   369  		})
   370  	}
   371  	// DSE v1
   372  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersionDse1} {
   373  		test.Run(version.String(), func(test *testing.T) {
   374  			tests := []encodeTestCase{
   375  				{
   376  					"rows result without column metadata",
   377  					&RowsResult{
   378  						Metadata: &RowsMetadata{
   379  							ColumnCount: 2,
   380  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   381  						},
   382  						Data: RowSet{row1, row2},
   383  					},
   384  					[]byte{
   385  						0, 0, 0, 2, // result type
   386  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
   387  						0, 0, 0, 2, // column count
   388  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   389  						0, 0, 0, 2, // rows count
   390  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   391  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   392  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   393  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   394  					},
   395  					nil,
   396  				},
   397  				{
   398  					"rows result with column metadata",
   399  					&RowsResult{
   400  						Metadata: &RowsMetadata{
   401  							ColumnCount: 2,
   402  							Columns:     []*ColumnMetadata{spec1, spec2},
   403  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   404  						},
   405  						Data: RowSet{row1, row2},
   406  					},
   407  					[]byte{
   408  						0, 0, 0, 2, // result type
   409  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
   410  						0, 0, 0, 2, // column count
   411  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   412  						0, 3, k, s, _1, // global ks
   413  						0, 6, t, a, b, l, e, _1, // global table
   414  						0, 4, c, o, l, _1, // col1 name
   415  						0, 9, // col1 type
   416  						0, 4, c, o, l, _2, // col2 name
   417  						0, 13, // col2 type
   418  						0, 0, 0, 2, // rows count
   419  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   420  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   421  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   422  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   423  					},
   424  					nil,
   425  				},
   426  				{
   427  					"rows result with column metadata no global table spec last page",
   428  					&RowsResult{
   429  						Metadata: &RowsMetadata{
   430  							ColumnCount: 2,
   431  							Columns:     []*ColumnMetadata{spec1, spec3},
   432  						},
   433  						Data: RowSet{row1, row2},
   434  					},
   435  					[]byte{
   436  						0, 0, 0, 2, // result type
   437  						0, 0, 0, 0, // flags
   438  						0, 0, 0, 2, // column count
   439  						0, 3, k, s, _1, // col1 ks
   440  						0, 6, t, a, b, l, e, _1, // col1 table
   441  						0, 4, c, o, l, _1, // col1 name
   442  						0, 9, // col1 type
   443  						0, 3, k, s, _1, // col2 ks
   444  						0, 6, t, a, b, l, e, _2, // col2 table
   445  						0, 4, c, o, l, _2, // col2 name
   446  						0, 13, // col2 type
   447  						0, 0, 0, 2, // rows count
   448  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   449  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   450  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   451  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   452  					},
   453  					nil,
   454  				},
   455  				{
   456  					"rows result with continuous paging",
   457  					&RowsResult{
   458  						Metadata: &RowsMetadata{
   459  							ColumnCount:          2,
   460  							Columns:              []*ColumnMetadata{spec1, spec2},
   461  							LastContinuousPage:   true,
   462  							ContinuousPageNumber: 42,
   463  						},
   464  						Data: RowSet{row1, row2},
   465  					},
   466  					[]byte{
   467  						0, 0, 0, 2, // result type
   468  						0b1100_0000, 0, 0, 1, // flags (last page | page no | global table spec)
   469  						0, 0, 0, 2, // column count
   470  						0, 0, 0, 42, // continuous paging number
   471  						0, 3, k, s, _1, // col1 ks
   472  						0, 6, t, a, b, l, e, _1, // col1 table
   473  						0, 4, c, o, l, _1, // col1 name
   474  						0, 9, // col1 type
   475  						0, 4, c, o, l, _2, // col2 name
   476  						0, 13, // col2 type
   477  						0, 0, 0, 2, // rows count
   478  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   479  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   480  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   481  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   482  					},
   483  					nil,
   484  				},
   485  			}
   486  			for _, tt := range tests {
   487  				test.Run(tt.name, func(t *testing.T) {
   488  					dest := &bytes.Buffer{}
   489  					err := codec.Encode(tt.input, dest, version)
   490  					assert.Equal(t, tt.expected, dest.Bytes())
   491  					assert.Equal(t, tt.err, err)
   492  				})
   493  			}
   494  		})
   495  	}
   496  	// DSE v2
   497  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersionDse2} {
   498  		test.Run(version.String(), func(test *testing.T) {
   499  			tests := []encodeTestCase{
   500  				{
   501  					"rows result without column metadata",
   502  					&RowsResult{
   503  						Metadata: &RowsMetadata{
   504  							ColumnCount: 2,
   505  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   506  						},
   507  						Data: RowSet{row1, row2},
   508  					},
   509  					[]byte{
   510  						0, 0, 0, 2, // result type
   511  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
   512  						0, 0, 0, 2, // column count
   513  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   514  						0, 0, 0, 2, // rows count
   515  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   516  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   517  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   518  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   519  					},
   520  					nil,
   521  				},
   522  				{
   523  					"rows result with column metadata",
   524  					&RowsResult{
   525  						Metadata: &RowsMetadata{
   526  							ColumnCount: 2,
   527  							Columns:     []*ColumnMetadata{spec1, spec2},
   528  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   529  						},
   530  						Data: RowSet{row1, row2},
   531  					},
   532  					[]byte{
   533  						0, 0, 0, 2, // result type
   534  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
   535  						0, 0, 0, 2, // column count
   536  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   537  						0, 3, k, s, _1, // global ks
   538  						0, 6, t, a, b, l, e, _1, // global table
   539  						0, 4, c, o, l, _1, // col1 name
   540  						0, 9, // col1 type
   541  						0, 4, c, o, l, _2, // col2 name
   542  						0, 13, // col2 type
   543  						0, 0, 0, 2, // rows count
   544  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   545  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   546  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   547  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   548  					},
   549  					nil,
   550  				},
   551  				{
   552  					"rows result with column metadata no global table spec last page",
   553  					&RowsResult{
   554  						Metadata: &RowsMetadata{
   555  							ColumnCount: 2,
   556  							Columns:     []*ColumnMetadata{spec1, spec3},
   557  						},
   558  						Data: RowSet{row1, row2},
   559  					},
   560  					[]byte{
   561  						0, 0, 0, 2, // result type
   562  						0, 0, 0, 0, // flags
   563  						0, 0, 0, 2, // column count
   564  						0, 3, k, s, _1, // col1 ks
   565  						0, 6, t, a, b, l, e, _1, // col1 table
   566  						0, 4, c, o, l, _1, // col1 name
   567  						0, 9, // col1 type
   568  						0, 3, k, s, _1, // col2 ks
   569  						0, 6, t, a, b, l, e, _2, // col2 table
   570  						0, 4, c, o, l, _2, // col2 name
   571  						0, 13, // col2 type
   572  						0, 0, 0, 2, // rows count
   573  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   574  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   575  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   576  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   577  					},
   578  					nil,
   579  				},
   580  				{
   581  					"rows result with column metadata and new result metadata id",
   582  					&RowsResult{
   583  						Metadata: &RowsMetadata{
   584  							NewResultMetadataId: []byte{1, 2, 3, 4},
   585  							ColumnCount:         2,
   586  							Columns:             []*ColumnMetadata{spec1, spec2},
   587  							PagingState:         []byte{0xca, 0xfe, 0xba, 0xbe},
   588  						},
   589  						Data: RowSet{row1, row2},
   590  					},
   591  					[]byte{
   592  						0, 0, 0, 2, // result type
   593  						0, 0, 0, 11, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES | METADATA_CHANGED)
   594  						0, 0, 0, 2, // column count
   595  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
   596  						0, 4, 1, 2, 3, 4, // new result metadata id
   597  						0, 3, k, s, _1, // global ks
   598  						0, 6, t, a, b, l, e, _1, // global table
   599  						0, 4, c, o, l, _1, // col1 name
   600  						0, 9, // col1 type
   601  						0, 4, c, o, l, _2, // col2 name
   602  						0, 13, // col2 type
   603  						0, 0, 0, 2, // rows count
   604  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   605  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   606  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   607  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   608  					},
   609  					nil,
   610  				},
   611  				{
   612  					"rows result with continuous paging",
   613  					&RowsResult{
   614  						Metadata: &RowsMetadata{
   615  							ColumnCount:          2,
   616  							Columns:              []*ColumnMetadata{spec1, spec2},
   617  							LastContinuousPage:   true,
   618  							ContinuousPageNumber: 42,
   619  						},
   620  						Data: RowSet{row1, row2},
   621  					},
   622  					[]byte{
   623  						0, 0, 0, 2, // result type
   624  						0b1100_0000, 0, 0, 1, // flags (last page | page no | global table spec)
   625  						0, 0, 0, 2, // column count
   626  						0, 0, 0, 42, // continuous paging number
   627  						0, 3, k, s, _1, // col1 ks
   628  						0, 6, t, a, b, l, e, _1, // col1 table
   629  						0, 4, c, o, l, _1, // col1 name
   630  						0, 9, // col1 type
   631  						0, 4, c, o, l, _2, // col2 name
   632  						0, 13, // col2 type
   633  						0, 0, 0, 2, // rows count
   634  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
   635  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
   636  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
   637  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
   638  					},
   639  					nil,
   640  				},
   641  			}
   642  			for _, tt := range tests {
   643  				test.Run(tt.name, func(t *testing.T) {
   644  					dest := &bytes.Buffer{}
   645  					err := codec.Encode(tt.input, dest, version)
   646  					assert.Equal(t, tt.expected, dest.Bytes())
   647  					assert.Equal(t, tt.err, err)
   648  				})
   649  			}
   650  		})
   651  	}
   652  }
   653  
   654  func TestResultCodec_EncodedLength_Rows(test *testing.T) {
   655  	row1 := [][]byte{
   656  		{0, 0, 0, 1},    // int = 1
   657  		{h, e, l, l, o}, // varchar = "hello"
   658  	}
   659  	row2 := [][]byte{
   660  		{0, 0, 0, 2},    // int = 2
   661  		{w, o, r, l, d}, // varchar = "world"
   662  	}
   663  	spec1 := &ColumnMetadata{
   664  		Keyspace: "ks1",
   665  		Table:    "table1",
   666  		Name:     "col1",
   667  		Index:    0,
   668  		Type:     datatype.Int,
   669  	}
   670  	spec2 := &ColumnMetadata{
   671  		Keyspace: "ks1",
   672  		Table:    "table1",
   673  		Name:     "col2",
   674  		Index:    0,
   675  		Type:     datatype.Varchar,
   676  	}
   677  	spec3 := &ColumnMetadata{
   678  		Keyspace: "ks1",
   679  		Table:    "table2",
   680  		Name:     "col2",
   681  		Index:    0,
   682  		Type:     datatype.Varchar,
   683  	}
   684  	codec := &resultCodec{}
   685  	// versions < 5
   686  	for _, version := range primitive.SupportedProtocolVersionsLesserThan(primitive.ProtocolVersion5) {
   687  		test.Run(version.String(), func(test *testing.T) {
   688  			tests := []encodedLengthTestCase{
   689  				{
   690  					"rows result without column metadata",
   691  					&RowsResult{
   692  						Metadata: &RowsMetadata{
   693  							ColumnCount: 2,
   694  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   695  						},
   696  						Data: RowSet{row1, row2},
   697  					},
   698  					primitive.LengthOfInt +
   699  						primitive.LengthOfInt +
   700  						primitive.LengthOfInt +
   701  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   702  						primitive.LengthOfInt +
   703  						8*2 + 9*2, // data
   704  					nil,
   705  				},
   706  				{
   707  					"rows result with column metadata",
   708  					&RowsResult{
   709  						Metadata: &RowsMetadata{
   710  							ColumnCount: 2,
   711  							Columns:     []*ColumnMetadata{spec1, spec2},
   712  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   713  						},
   714  						Data: RowSet{row1, row2},
   715  					},
   716  					primitive.LengthOfInt +
   717  						primitive.LengthOfInt +
   718  						primitive.LengthOfInt +
   719  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   720  						primitive.LengthOfString("ks1") +
   721  						primitive.LengthOfString("table1") +
   722  						primitive.LengthOfString("col1") +
   723  						primitive.LengthOfShort +
   724  						primitive.LengthOfString("col2") +
   725  						primitive.LengthOfShort +
   726  						primitive.LengthOfInt +
   727  						8*2 + 9*2, // data
   728  					nil,
   729  				},
   730  				{
   731  					"rows result with column metadata no global table spec last page",
   732  					&RowsResult{
   733  						Metadata: &RowsMetadata{
   734  							ColumnCount: 2,
   735  							Columns:     []*ColumnMetadata{spec1, spec3},
   736  						},
   737  						Data: RowSet{row1, row2},
   738  					},
   739  					primitive.LengthOfInt +
   740  						primitive.LengthOfInt +
   741  						primitive.LengthOfInt +
   742  						primitive.LengthOfString("ks1") +
   743  						primitive.LengthOfString("table1") +
   744  						primitive.LengthOfString("col1") +
   745  						primitive.LengthOfShort +
   746  						primitive.LengthOfString("ks1") +
   747  						primitive.LengthOfString("table2") +
   748  						primitive.LengthOfString("col2") +
   749  						primitive.LengthOfShort +
   750  						primitive.LengthOfInt +
   751  						8*2 + 9*2, // data
   752  					nil,
   753  				},
   754  			}
   755  			for _, tt := range tests {
   756  				test.Run(tt.name, func(t *testing.T) {
   757  					actual, err := codec.EncodedLength(tt.input, version)
   758  					assert.Equal(t, tt.expected, actual)
   759  					assert.Equal(t, tt.err, err)
   760  				})
   761  			}
   762  		})
   763  	}
   764  	// version = 5
   765  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersion5} {
   766  		test.Run(version.String(), func(test *testing.T) {
   767  			tests := []encodedLengthTestCase{
   768  				{
   769  					"rows result without column metadata",
   770  					&RowsResult{
   771  						Metadata: &RowsMetadata{
   772  							ColumnCount: 2,
   773  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   774  						},
   775  						Data: RowSet{row1, row2},
   776  					},
   777  					primitive.LengthOfInt +
   778  						primitive.LengthOfInt +
   779  						primitive.LengthOfInt +
   780  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   781  						primitive.LengthOfInt +
   782  						8*2 + 9*2, // data
   783  					nil,
   784  				},
   785  				{
   786  					"rows result with column metadata",
   787  					&RowsResult{
   788  						Metadata: &RowsMetadata{
   789  							ColumnCount: 2,
   790  							Columns:     []*ColumnMetadata{spec1, spec2},
   791  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   792  						},
   793  						Data: RowSet{row1, row2},
   794  					},
   795  					primitive.LengthOfInt +
   796  						primitive.LengthOfInt +
   797  						primitive.LengthOfInt +
   798  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   799  						primitive.LengthOfString("ks1") +
   800  						primitive.LengthOfString("table1") +
   801  						primitive.LengthOfString("col1") +
   802  						primitive.LengthOfShort +
   803  						primitive.LengthOfString("col2") +
   804  						primitive.LengthOfShort +
   805  						primitive.LengthOfInt +
   806  						8*2 + 9*2, // data
   807  					nil,
   808  				},
   809  				{
   810  					"rows result with column metadata no global table spec last page",
   811  					&RowsResult{
   812  						Metadata: &RowsMetadata{
   813  							ColumnCount: 2,
   814  							Columns:     []*ColumnMetadata{spec1, spec3},
   815  						},
   816  						Data: RowSet{row1, row2},
   817  					},
   818  					primitive.LengthOfInt +
   819  						primitive.LengthOfInt +
   820  						primitive.LengthOfInt +
   821  						primitive.LengthOfString("ks1") +
   822  						primitive.LengthOfString("table1") +
   823  						primitive.LengthOfString("col1") +
   824  						primitive.LengthOfShort +
   825  						primitive.LengthOfString("ks1") +
   826  						primitive.LengthOfString("table2") +
   827  						primitive.LengthOfString("col2") +
   828  						primitive.LengthOfShort +
   829  						primitive.LengthOfInt +
   830  						8*2 + 9*2, // data
   831  					nil,
   832  				},
   833  				{
   834  					"rows result with column metadata and new result metadata id",
   835  					&RowsResult{
   836  						Metadata: &RowsMetadata{
   837  							NewResultMetadataId: []byte{1, 2, 3, 4},
   838  							ColumnCount:         2,
   839  							Columns:             []*ColumnMetadata{spec1, spec2},
   840  							PagingState:         []byte{0xca, 0xfe, 0xba, 0xbe},
   841  						},
   842  						Data: RowSet{row1, row2},
   843  					},
   844  					primitive.LengthOfInt +
   845  						primitive.LengthOfInt +
   846  						primitive.LengthOfInt +
   847  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   848  						primitive.LengthOfShortBytes([]byte{1, 2, 3, 4}) +
   849  						primitive.LengthOfString("ks1") +
   850  						primitive.LengthOfString("table1") +
   851  						primitive.LengthOfString("col1") +
   852  						primitive.LengthOfShort +
   853  						primitive.LengthOfString("col2") +
   854  						primitive.LengthOfShort +
   855  						primitive.LengthOfInt +
   856  						8*2 + 9*2, // data
   857  					nil,
   858  				},
   859  			}
   860  			for _, tt := range tests {
   861  				test.Run(tt.name, func(t *testing.T) {
   862  					actual, err := codec.EncodedLength(tt.input, version)
   863  					assert.Equal(t, tt.expected, actual)
   864  					assert.Equal(t, tt.err, err)
   865  				})
   866  			}
   867  		})
   868  	}
   869  	// DSE v1
   870  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersionDse1} {
   871  		test.Run(version.String(), func(test *testing.T) {
   872  			tests := []encodedLengthTestCase{
   873  				{
   874  					"rows result without column metadata",
   875  					&RowsResult{
   876  						Metadata: &RowsMetadata{
   877  							ColumnCount: 2,
   878  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   879  						},
   880  						Data: RowSet{row1, row2},
   881  					},
   882  					primitive.LengthOfInt +
   883  						primitive.LengthOfInt +
   884  						primitive.LengthOfInt +
   885  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   886  						primitive.LengthOfInt +
   887  						8*2 + 9*2, // data
   888  					nil,
   889  				},
   890  				{
   891  					"rows result with column metadata",
   892  					&RowsResult{
   893  						Metadata: &RowsMetadata{
   894  							ColumnCount: 2,
   895  							Columns:     []*ColumnMetadata{spec1, spec2},
   896  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   897  						},
   898  						Data: RowSet{row1, row2},
   899  					},
   900  					primitive.LengthOfInt +
   901  						primitive.LengthOfInt +
   902  						primitive.LengthOfInt +
   903  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   904  						primitive.LengthOfString("ks1") +
   905  						primitive.LengthOfString("table1") +
   906  						primitive.LengthOfString("col1") +
   907  						primitive.LengthOfShort +
   908  						primitive.LengthOfString("col2") +
   909  						primitive.LengthOfShort +
   910  						primitive.LengthOfInt +
   911  						8*2 + 9*2, // data
   912  					nil,
   913  				},
   914  				{
   915  					"rows result with column metadata no global table spec last page",
   916  					&RowsResult{
   917  						Metadata: &RowsMetadata{
   918  							ColumnCount: 2,
   919  							Columns:     []*ColumnMetadata{spec1, spec3},
   920  						},
   921  						Data: RowSet{row1, row2},
   922  					},
   923  					primitive.LengthOfInt +
   924  						primitive.LengthOfInt +
   925  						primitive.LengthOfInt +
   926  						primitive.LengthOfString("ks1") +
   927  						primitive.LengthOfString("table1") +
   928  						primitive.LengthOfString("col1") +
   929  						primitive.LengthOfShort +
   930  						primitive.LengthOfString("ks1") +
   931  						primitive.LengthOfString("table2") +
   932  						primitive.LengthOfString("col2") +
   933  						primitive.LengthOfShort +
   934  						primitive.LengthOfInt +
   935  						8*2 + 9*2, // data
   936  					nil,
   937  				},
   938  				{
   939  					"rows result with continuous paging",
   940  					&RowsResult{
   941  						Metadata: &RowsMetadata{
   942  							ColumnCount:          2,
   943  							Columns:              []*ColumnMetadata{spec1, spec2},
   944  							LastContinuousPage:   true,
   945  							ContinuousPageNumber: 42,
   946  						},
   947  						Data: RowSet{row1, row2},
   948  					},
   949  					primitive.LengthOfInt +
   950  						primitive.LengthOfInt +
   951  						primitive.LengthOfInt +
   952  						primitive.LengthOfInt +
   953  						primitive.LengthOfString("ks1") +
   954  						primitive.LengthOfString("table1") +
   955  						primitive.LengthOfString("col1") +
   956  						primitive.LengthOfShort +
   957  						primitive.LengthOfString("col2") +
   958  						primitive.LengthOfShort +
   959  						primitive.LengthOfInt +
   960  						8*2 + 9*2, // data
   961  					nil,
   962  				},
   963  			}
   964  			for _, tt := range tests {
   965  				test.Run(tt.name, func(t *testing.T) {
   966  					actual, err := codec.EncodedLength(tt.input, version)
   967  					assert.Equal(t, tt.expected, actual)
   968  					assert.Equal(t, tt.err, err)
   969  				})
   970  			}
   971  		})
   972  	}
   973  	// DSE v2
   974  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersionDse2} {
   975  		test.Run(version.String(), func(test *testing.T) {
   976  			tests := []encodedLengthTestCase{
   977  				{
   978  					"rows result without column metadata",
   979  					&RowsResult{
   980  						Metadata: &RowsMetadata{
   981  							ColumnCount: 2,
   982  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
   983  						},
   984  						Data: RowSet{row1, row2},
   985  					},
   986  					primitive.LengthOfInt +
   987  						primitive.LengthOfInt +
   988  						primitive.LengthOfInt +
   989  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
   990  						primitive.LengthOfInt +
   991  						8*2 + 9*2, // data
   992  					nil,
   993  				},
   994  				{
   995  					"rows result with column metadata",
   996  					&RowsResult{
   997  						Metadata: &RowsMetadata{
   998  							ColumnCount: 2,
   999  							Columns:     []*ColumnMetadata{spec1, spec2},
  1000  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1001  						},
  1002  						Data: RowSet{row1, row2},
  1003  					},
  1004  					primitive.LengthOfInt +
  1005  						primitive.LengthOfInt +
  1006  						primitive.LengthOfInt +
  1007  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
  1008  						primitive.LengthOfString("ks1") +
  1009  						primitive.LengthOfString("table1") +
  1010  						primitive.LengthOfString("col1") +
  1011  						primitive.LengthOfShort +
  1012  						primitive.LengthOfString("col2") +
  1013  						primitive.LengthOfShort +
  1014  						primitive.LengthOfInt +
  1015  						8*2 + 9*2, // data
  1016  					nil,
  1017  				},
  1018  				{
  1019  					"rows result with column metadata no global table spec last page",
  1020  					&RowsResult{
  1021  						Metadata: &RowsMetadata{
  1022  							ColumnCount: 2,
  1023  							Columns:     []*ColumnMetadata{spec1, spec3},
  1024  						},
  1025  						Data: RowSet{row1, row2},
  1026  					},
  1027  					primitive.LengthOfInt +
  1028  						primitive.LengthOfInt +
  1029  						primitive.LengthOfInt +
  1030  						primitive.LengthOfString("ks1") +
  1031  						primitive.LengthOfString("table1") +
  1032  						primitive.LengthOfString("col1") +
  1033  						primitive.LengthOfShort +
  1034  						primitive.LengthOfString("ks1") +
  1035  						primitive.LengthOfString("table2") +
  1036  						primitive.LengthOfString("col2") +
  1037  						primitive.LengthOfShort +
  1038  						primitive.LengthOfInt +
  1039  						8*2 + 9*2, // data
  1040  					nil,
  1041  				},
  1042  				{
  1043  					"rows result with column metadata and new result metadata id",
  1044  					&RowsResult{
  1045  						Metadata: &RowsMetadata{
  1046  							NewResultMetadataId: []byte{1, 2, 3, 4},
  1047  							ColumnCount:         2,
  1048  							Columns:             []*ColumnMetadata{spec1, spec2},
  1049  							PagingState:         []byte{0xca, 0xfe, 0xba, 0xbe},
  1050  						},
  1051  						Data: RowSet{row1, row2},
  1052  					},
  1053  					primitive.LengthOfInt +
  1054  						primitive.LengthOfInt +
  1055  						primitive.LengthOfInt +
  1056  						primitive.LengthOfBytes([]byte{0xca, 0xfe, 0xba, 0xbe}) +
  1057  						primitive.LengthOfShortBytes([]byte{1, 2, 3, 4}) +
  1058  						primitive.LengthOfString("ks1") +
  1059  						primitive.LengthOfString("table1") +
  1060  						primitive.LengthOfString("col1") +
  1061  						primitive.LengthOfShort +
  1062  						primitive.LengthOfString("col2") +
  1063  						primitive.LengthOfShort +
  1064  						primitive.LengthOfInt +
  1065  						8*2 + 9*2, // data
  1066  					nil,
  1067  				},
  1068  				{
  1069  					"rows result with continuous paging",
  1070  					&RowsResult{
  1071  						Metadata: &RowsMetadata{
  1072  							ColumnCount:          2,
  1073  							Columns:              []*ColumnMetadata{spec1, spec2},
  1074  							LastContinuousPage:   true,
  1075  							ContinuousPageNumber: 42,
  1076  						},
  1077  						Data: RowSet{row1, row2},
  1078  					},
  1079  					primitive.LengthOfInt +
  1080  						primitive.LengthOfInt +
  1081  						primitive.LengthOfInt +
  1082  						primitive.LengthOfInt +
  1083  						primitive.LengthOfString("ks1") +
  1084  						primitive.LengthOfString("table1") +
  1085  						primitive.LengthOfString("col1") +
  1086  						primitive.LengthOfShort +
  1087  						primitive.LengthOfString("col2") +
  1088  						primitive.LengthOfShort +
  1089  						primitive.LengthOfInt +
  1090  						8*2 + 9*2, // data
  1091  					nil,
  1092  				},
  1093  			}
  1094  			for _, tt := range tests {
  1095  				test.Run(tt.name, func(t *testing.T) {
  1096  					actual, err := codec.EncodedLength(tt.input, version)
  1097  					assert.Equal(t, tt.expected, actual)
  1098  					assert.Equal(t, tt.err, err)
  1099  				})
  1100  			}
  1101  		})
  1102  	}
  1103  }
  1104  
  1105  func TestResultCodec_Decode_Rows(test *testing.T) {
  1106  	row1 := [][]byte{
  1107  		{0, 0, 0, 1},    // int = 1
  1108  		{h, e, l, l, o}, // varchar = "hello"
  1109  	}
  1110  	row2 := [][]byte{
  1111  		{0, 0, 0, 2},    // int = 2
  1112  		{w, o, r, l, d}, // varchar = "world"
  1113  	}
  1114  	spec1 := &ColumnMetadata{
  1115  		Keyspace: "ks1",
  1116  		Table:    "table1",
  1117  		Name:     "col1",
  1118  		Index:    0,
  1119  		Type:     datatype.Int,
  1120  	}
  1121  	spec2 := &ColumnMetadata{
  1122  		Keyspace: "ks1",
  1123  		Table:    "table1",
  1124  		Name:     "col2",
  1125  		Index:    0,
  1126  		Type:     datatype.Varchar,
  1127  	}
  1128  	spec3 := &ColumnMetadata{
  1129  		Keyspace: "ks1",
  1130  		Table:    "table2",
  1131  		Name:     "col2",
  1132  		Index:    0,
  1133  		Type:     datatype.Varchar,
  1134  	}
  1135  	codec := &resultCodec{}
  1136  	// versions < 5
  1137  	for _, version := range primitive.SupportedProtocolVersionsLesserThan(primitive.ProtocolVersion5) {
  1138  		test.Run(version.String(), func(test *testing.T) {
  1139  			tests := []decodeTestCase{
  1140  				{
  1141  					"rows result without column metadata",
  1142  					[]byte{
  1143  						0, 0, 0, 2, // result type
  1144  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
  1145  						0, 0, 0, 2, // column count
  1146  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1147  						0, 0, 0, 2, // rows count
  1148  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1149  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1150  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1151  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1152  					},
  1153  					&RowsResult{
  1154  						Metadata: &RowsMetadata{
  1155  							ColumnCount: 2,
  1156  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1157  						},
  1158  						Data: RowSet{row1, row2},
  1159  					},
  1160  					nil,
  1161  				},
  1162  				{
  1163  					"rows result with column metadata",
  1164  					[]byte{
  1165  						0, 0, 0, 2, // result type
  1166  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
  1167  						0, 0, 0, 2, // column count
  1168  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1169  						0, 3, k, s, _1, // global ks
  1170  						0, 6, t, a, b, l, e, _1, // global table
  1171  						0, 4, c, o, l, _1, // col1 name
  1172  						0, 9, // col1 type
  1173  						0, 4, c, o, l, _2, // col2 name
  1174  						0, 13, // col2 type
  1175  						0, 0, 0, 2, // rows count
  1176  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1177  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1178  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1179  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1180  					},
  1181  					&RowsResult{
  1182  						Metadata: &RowsMetadata{
  1183  							ColumnCount: 2,
  1184  							Columns:     []*ColumnMetadata{spec1, spec2},
  1185  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1186  						},
  1187  						Data: RowSet{row1, row2},
  1188  					},
  1189  					nil,
  1190  				},
  1191  				{
  1192  					"rows result with column metadata no global table spec last page",
  1193  					[]byte{
  1194  						0, 0, 0, 2, // result type
  1195  						0, 0, 0, 0, // flags
  1196  						0, 0, 0, 2, // column count
  1197  						0, 3, k, s, _1, // col1 ks
  1198  						0, 6, t, a, b, l, e, _1, // col1 table
  1199  						0, 4, c, o, l, _1, // col1 name
  1200  						0, 9, // col1 type
  1201  						0, 3, k, s, _1, // col2 ks
  1202  						0, 6, t, a, b, l, e, _2, // col2 table
  1203  						0, 4, c, o, l, _2, // col2 name
  1204  						0, 13, // col2 type
  1205  						0, 0, 0, 2, // rows count
  1206  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1207  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1208  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1209  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1210  					},
  1211  					&RowsResult{
  1212  						Metadata: &RowsMetadata{
  1213  							ColumnCount: 2,
  1214  							Columns:     []*ColumnMetadata{spec1, spec3},
  1215  						},
  1216  						Data: RowSet{row1, row2},
  1217  					},
  1218  					nil,
  1219  				},
  1220  			}
  1221  			for _, tt := range tests {
  1222  				test.Run(tt.name, func(t *testing.T) {
  1223  					source := bytes.NewBuffer(tt.input)
  1224  					actual, err := codec.Decode(source, version)
  1225  					assert.Equal(t, tt.expected, actual)
  1226  					assert.Equal(t, tt.err, err)
  1227  				})
  1228  			}
  1229  		})
  1230  	}
  1231  	// versions = 5
  1232  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersion5} {
  1233  		test.Run(version.String(), func(test *testing.T) {
  1234  			tests := []decodeTestCase{
  1235  				{
  1236  					"rows result without column metadata",
  1237  					[]byte{
  1238  						0, 0, 0, 2, // result type
  1239  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
  1240  						0, 0, 0, 2, // column count
  1241  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1242  						0, 0, 0, 2, // rows count
  1243  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1244  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1245  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1246  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1247  					},
  1248  					&RowsResult{
  1249  						Metadata: &RowsMetadata{
  1250  							ColumnCount: 2,
  1251  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1252  						},
  1253  						Data: RowSet{row1, row2},
  1254  					},
  1255  					nil,
  1256  				},
  1257  				{
  1258  					"rows result with column metadata",
  1259  					[]byte{
  1260  						0, 0, 0, 2, // result type
  1261  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
  1262  						0, 0, 0, 2, // column count
  1263  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1264  						0, 3, k, s, _1, // global ks
  1265  						0, 6, t, a, b, l, e, _1, // global table
  1266  						0, 4, c, o, l, _1, // col1 name
  1267  						0, 9, // col1 type
  1268  						0, 4, c, o, l, _2, // col2 name
  1269  						0, 13, // col2 type
  1270  						0, 0, 0, 2, // rows count
  1271  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1272  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1273  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1274  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1275  					},
  1276  					&RowsResult{
  1277  						Metadata: &RowsMetadata{
  1278  							ColumnCount: 2,
  1279  							Columns:     []*ColumnMetadata{spec1, spec2},
  1280  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1281  						},
  1282  						Data: RowSet{row1, row2},
  1283  					},
  1284  					nil,
  1285  				},
  1286  				{
  1287  					"rows result with column metadata no global table spec last page",
  1288  					[]byte{
  1289  						0, 0, 0, 2, // result type
  1290  						0, 0, 0, 0, // flags
  1291  						0, 0, 0, 2, // column count
  1292  						0, 3, k, s, _1, // col1 ks
  1293  						0, 6, t, a, b, l, e, _1, // col1 table
  1294  						0, 4, c, o, l, _1, // col1 name
  1295  						0, 9, // col1 type
  1296  						0, 3, k, s, _1, // col2 ks
  1297  						0, 6, t, a, b, l, e, _2, // col2 table
  1298  						0, 4, c, o, l, _2, // col2 name
  1299  						0, 13, // col2 type
  1300  						0, 0, 0, 2, // rows count
  1301  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1302  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1303  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1304  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1305  					},
  1306  					&RowsResult{
  1307  						Metadata: &RowsMetadata{
  1308  							ColumnCount: 2,
  1309  							Columns:     []*ColumnMetadata{spec1, spec3},
  1310  						},
  1311  						Data: RowSet{row1, row2},
  1312  					},
  1313  					nil,
  1314  				},
  1315  			}
  1316  			for _, tt := range tests {
  1317  				test.Run(tt.name, func(t *testing.T) {
  1318  					source := bytes.NewBuffer(tt.input)
  1319  					actual, err := codec.Decode(source, version)
  1320  					assert.Equal(t, tt.expected, actual)
  1321  					assert.Equal(t, tt.err, err)
  1322  				})
  1323  			}
  1324  		})
  1325  	}
  1326  	// DSE v1
  1327  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersionDse1} {
  1328  		test.Run(version.String(), func(test *testing.T) {
  1329  			tests := []decodeTestCase{
  1330  				{
  1331  					"rows result without column metadata",
  1332  					[]byte{
  1333  						0, 0, 0, 2, // result type
  1334  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
  1335  						0, 0, 0, 2, // column count
  1336  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1337  						0, 0, 0, 2, // rows count
  1338  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1339  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1340  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1341  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1342  					},
  1343  					&RowsResult{
  1344  						Metadata: &RowsMetadata{
  1345  							ColumnCount: 2,
  1346  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1347  						},
  1348  						Data: RowSet{row1, row2},
  1349  					},
  1350  					nil,
  1351  				},
  1352  				{
  1353  					"rows result with column metadata",
  1354  					[]byte{
  1355  						0, 0, 0, 2, // result type
  1356  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
  1357  						0, 0, 0, 2, // column count
  1358  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1359  						0, 3, k, s, _1, // global ks
  1360  						0, 6, t, a, b, l, e, _1, // global table
  1361  						0, 4, c, o, l, _1, // col1 name
  1362  						0, 9, // col1 type
  1363  						0, 4, c, o, l, _2, // col2 name
  1364  						0, 13, // col2 type
  1365  						0, 0, 0, 2, // rows count
  1366  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1367  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1368  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1369  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1370  					},
  1371  					&RowsResult{
  1372  						Metadata: &RowsMetadata{
  1373  							ColumnCount: 2,
  1374  							Columns:     []*ColumnMetadata{spec1, spec2},
  1375  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1376  						},
  1377  						Data: RowSet{row1, row2},
  1378  					},
  1379  					nil,
  1380  				},
  1381  				{
  1382  					"rows result with column metadata no global table spec last page",
  1383  					[]byte{
  1384  						0, 0, 0, 2, // result type
  1385  						0, 0, 0, 0, // flags
  1386  						0, 0, 0, 2, // column count
  1387  						0, 3, k, s, _1, // col1 ks
  1388  						0, 6, t, a, b, l, e, _1, // col1 table
  1389  						0, 4, c, o, l, _1, // col1 name
  1390  						0, 9, // col1 type
  1391  						0, 3, k, s, _1, // col2 ks
  1392  						0, 6, t, a, b, l, e, _2, // col2 table
  1393  						0, 4, c, o, l, _2, // col2 name
  1394  						0, 13, // col2 type
  1395  						0, 0, 0, 2, // rows count
  1396  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1397  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1398  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1399  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1400  					},
  1401  					&RowsResult{
  1402  						Metadata: &RowsMetadata{
  1403  							ColumnCount: 2,
  1404  							Columns:     []*ColumnMetadata{spec1, spec3},
  1405  						},
  1406  						Data: RowSet{row1, row2},
  1407  					},
  1408  					nil,
  1409  				},
  1410  				{
  1411  					"rows result with continuous paging",
  1412  					[]byte{
  1413  						0, 0, 0, 2, // result type
  1414  						0b1100_0000, 0, 0, 1, // flags (last page | page no | global table spec)
  1415  						0, 0, 0, 2, // column count
  1416  						0, 0, 0, 42, // continuous paging number
  1417  						0, 3, k, s, _1, // col1 ks
  1418  						0, 6, t, a, b, l, e, _1, // col1 table
  1419  						0, 4, c, o, l, _1, // col1 name
  1420  						0, 9, // col1 type
  1421  						0, 4, c, o, l, _2, // col2 name
  1422  						0, 13, // col2 type
  1423  						0, 0, 0, 2, // rows count
  1424  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1425  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1426  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1427  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1428  					},
  1429  					&RowsResult{
  1430  						Metadata: &RowsMetadata{
  1431  							ColumnCount:          2,
  1432  							Columns:              []*ColumnMetadata{spec1, spec2},
  1433  							LastContinuousPage:   true,
  1434  							ContinuousPageNumber: 42,
  1435  						},
  1436  						Data: RowSet{row1, row2},
  1437  					},
  1438  					nil,
  1439  				},
  1440  			}
  1441  			for _, tt := range tests {
  1442  				test.Run(tt.name, func(t *testing.T) {
  1443  					source := bytes.NewBuffer(tt.input)
  1444  					actual, err := codec.Decode(source, version)
  1445  					assert.Equal(t, tt.expected, actual)
  1446  					assert.Equal(t, tt.err, err)
  1447  				})
  1448  			}
  1449  		})
  1450  	}
  1451  	// DSE v2
  1452  	for _, version := range []primitive.ProtocolVersion{primitive.ProtocolVersionDse2} {
  1453  		test.Run(version.String(), func(test *testing.T) {
  1454  			tests := []decodeTestCase{
  1455  				{
  1456  					"rows result without column metadata",
  1457  					[]byte{
  1458  						0, 0, 0, 2, // result type
  1459  						0, 0, 0, 6, // flags (HAS_MORE_PAGES | NO_METADATA)
  1460  						0, 0, 0, 2, // column count
  1461  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1462  						0, 0, 0, 2, // rows count
  1463  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1464  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1465  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1466  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1467  					},
  1468  					&RowsResult{
  1469  						Metadata: &RowsMetadata{
  1470  							ColumnCount: 2,
  1471  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1472  						},
  1473  						Data: RowSet{row1, row2},
  1474  					},
  1475  					nil,
  1476  				},
  1477  				{
  1478  					"rows result with column metadata",
  1479  					[]byte{
  1480  						0, 0, 0, 2, // result type
  1481  						0, 0, 0, 3, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES)
  1482  						0, 0, 0, 2, // column count
  1483  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1484  						0, 3, k, s, _1, // global ks
  1485  						0, 6, t, a, b, l, e, _1, // global table
  1486  						0, 4, c, o, l, _1, // col1 name
  1487  						0, 9, // col1 type
  1488  						0, 4, c, o, l, _2, // col2 name
  1489  						0, 13, // col2 type
  1490  						0, 0, 0, 2, // rows count
  1491  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1492  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1493  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1494  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1495  					},
  1496  					&RowsResult{
  1497  						Metadata: &RowsMetadata{
  1498  							ColumnCount: 2,
  1499  							Columns:     []*ColumnMetadata{spec1, spec2},
  1500  							PagingState: []byte{0xca, 0xfe, 0xba, 0xbe},
  1501  						},
  1502  						Data: RowSet{row1, row2},
  1503  					},
  1504  					nil,
  1505  				},
  1506  				{
  1507  					"rows result with column metadata no global table spec last page",
  1508  					[]byte{
  1509  						0, 0, 0, 2, // result type
  1510  						0, 0, 0, 0, // flags
  1511  						0, 0, 0, 2, // column count
  1512  						0, 3, k, s, _1, // col1 ks
  1513  						0, 6, t, a, b, l, e, _1, // col1 table
  1514  						0, 4, c, o, l, _1, // col1 name
  1515  						0, 9, // col1 type
  1516  						0, 3, k, s, _1, // col2 ks
  1517  						0, 6, t, a, b, l, e, _2, // col2 table
  1518  						0, 4, c, o, l, _2, // col2 name
  1519  						0, 13, // col2 type
  1520  						0, 0, 0, 2, // rows count
  1521  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1522  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1523  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1524  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1525  					},
  1526  					&RowsResult{
  1527  						Metadata: &RowsMetadata{
  1528  							ColumnCount: 2,
  1529  							Columns:     []*ColumnMetadata{spec1, spec3},
  1530  						},
  1531  						Data: RowSet{row1, row2},
  1532  					},
  1533  					nil,
  1534  				},
  1535  				{
  1536  					"rows result with column metadata and new result metadata id",
  1537  					[]byte{
  1538  						0, 0, 0, 2, // result type
  1539  						0, 0, 0, 11, // flags (GLOBAL_TABLE_SPEC | HAS_MORE_PAGES | METADATA_CHANGED)
  1540  						0, 0, 0, 2, // column count
  1541  						0, 0, 0, 4, 0xca, 0xfe, 0xba, 0xbe, // paging state
  1542  						0, 4, 1, 2, 3, 4, // new result metadata id
  1543  						0, 3, k, s, _1, // global ks
  1544  						0, 6, t, a, b, l, e, _1, // global table
  1545  						0, 4, c, o, l, _1, // col1 name
  1546  						0, 9, // col1 type
  1547  						0, 4, c, o, l, _2, // col2 name
  1548  						0, 13, // col2 type
  1549  						0, 0, 0, 2, // rows count
  1550  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1551  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1552  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1553  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1554  					},
  1555  					&RowsResult{
  1556  						Metadata: &RowsMetadata{
  1557  							NewResultMetadataId: []byte{1, 2, 3, 4},
  1558  							ColumnCount:         2,
  1559  							Columns:             []*ColumnMetadata{spec1, spec2},
  1560  							PagingState:         []byte{0xca, 0xfe, 0xba, 0xbe},
  1561  						},
  1562  						Data: RowSet{row1, row2},
  1563  					},
  1564  					nil,
  1565  				},
  1566  				{
  1567  					"rows result with continuous paging",
  1568  					[]byte{
  1569  						0, 0, 0, 2, // result type
  1570  						0b1100_0000, 0, 0, 1, // flags (last page | page no | global table spec)
  1571  						0, 0, 0, 2, // column count
  1572  						0, 0, 0, 42, // continuous paging number
  1573  						0, 3, k, s, _1, // col1 ks
  1574  						0, 6, t, a, b, l, e, _1, // col1 table
  1575  						0, 4, c, o, l, _1, // col1 name
  1576  						0, 9, // col1 type
  1577  						0, 4, c, o, l, _2, // col2 name
  1578  						0, 13, // col2 type
  1579  						0, 0, 0, 2, // rows count
  1580  						0, 0, 0, 4, 0, 0, 0, 1, // row1, col1
  1581  						0, 0, 0, 5, h, e, l, l, o, // row1, col2
  1582  						0, 0, 0, 4, 0, 0, 0, 2, // row2, col1
  1583  						0, 0, 0, 5, w, o, r, l, d, // row2, col2
  1584  					},
  1585  					&RowsResult{
  1586  						Metadata: &RowsMetadata{
  1587  							ColumnCount:          2,
  1588  							Columns:              []*ColumnMetadata{spec1, spec2},
  1589  							LastContinuousPage:   true,
  1590  							ContinuousPageNumber: 42,
  1591  						},
  1592  						Data: RowSet{row1, row2},
  1593  					},
  1594  					nil,
  1595  				},
  1596  			}
  1597  			for _, tt := range tests {
  1598  				test.Run(tt.name, func(t *testing.T) {
  1599  					source := bytes.NewBuffer(tt.input)
  1600  					actual, err := codec.Decode(source, version)
  1601  					assert.Equal(t, tt.expected, actual)
  1602  					assert.Equal(t, tt.err, err)
  1603  				})
  1604  			}
  1605  		})
  1606  	}
  1607  }