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 }