github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/merger/sortmerger/heap_test.go (about) 1 // Copyright 2021 ecodeclub 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 sortmerger 16 17 import ( 18 "container/heap" 19 "database/sql" 20 "reflect" 21 "testing" 22 "time" 23 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 ) 27 28 func newTestHp(nodes []*node, columns sortColumns) *Heap { 29 h := &Heap{ 30 sortColumns: columns, 31 } 32 for _, node := range nodes { 33 heap.Push(h, node) 34 } 35 return h 36 } 37 38 func newTestNodes(sortColsList [][]any) []*node { 39 res := make([]*node, 0, len(sortColsList)) 40 for _, sortCols := range sortColsList { 41 n := &node{ 42 sortCols: sortCols, 43 } 44 res = append(res, n) 45 } 46 return res 47 } 48 49 func TestHeap(t *testing.T) { 50 testcases := []struct { 51 name string 52 nodes func() []*node 53 wantNodes func() []*node 54 sortCols func() sortColumns 55 }{ 56 { 57 name: "单个列升序", 58 nodes: func() []*node { 59 return newTestNodes([][]any{ 60 {2}, 61 {5}, 62 {6}, 63 {1}, 64 {0}, 65 }) 66 }, 67 wantNodes: func() []*node { 68 return newTestNodes([][]any{ 69 {0}, 70 {1}, 71 {2}, 72 {5}, 73 {6}, 74 }) 75 }, 76 sortCols: func() sortColumns { 77 sortCols, err := newSortColumns(NewSortColumn("id", ASC)) 78 require.NoError(t, err) 79 return sortCols 80 }, 81 }, 82 { 83 name: "单个列降序", 84 nodes: func() []*node { 85 return newTestNodes([][]any{ 86 {2}, 87 {5}, 88 {6}, 89 {1}, 90 {0}, 91 }) 92 }, 93 wantNodes: func() []*node { 94 return newTestNodes([][]any{ 95 {6}, 96 {5}, 97 {2}, 98 {1}, 99 {0}, 100 }) 101 }, 102 sortCols: func() sortColumns { 103 sortCols, err := newSortColumns(NewSortColumn("id", DESC)) 104 require.NoError(t, err) 105 return sortCols 106 }, 107 }, 108 { 109 name: "三个列顺序:升序,降序,升序", 110 nodes: func() []*node { 111 return newTestNodes([][]any{ 112 {2, "b", 1}, 113 {2, "a", 1}, 114 {2, "e", 2}, 115 {2, "e", 1}, 116 {2, "e", 3}, 117 {5, "b", 1}, 118 {5, "a", 1}, 119 {5, "e", 2}, 120 {5, "e", 1}, 121 {5, "e", 3}, 122 {1, "b", 1}, 123 {1, "a", 1}, 124 {1, "e", 2}, 125 {1, "e", 1}, 126 {1, "e", 3}, 127 }) 128 }, 129 wantNodes: func() []*node { 130 return newTestNodes([][]any{ 131 {1, "e", 1}, 132 {1, "e", 2}, 133 {1, "e", 3}, 134 {1, "b", 1}, 135 {1, "a", 1}, 136 {2, "e", 1}, 137 {2, "e", 2}, 138 {2, "e", 3}, 139 {2, "b", 1}, 140 {2, "a", 1}, 141 {5, "e", 1}, 142 {5, "e", 2}, 143 {5, "e", 3}, 144 {5, "b", 1}, 145 {5, "a", 1}, 146 }) 147 }, 148 sortCols: func() sortColumns { 149 sortCols, err := newSortColumns(NewSortColumn("id", ASC), NewSortColumn("name", DESC), NewSortColumn("age", ASC)) 150 require.NoError(t, err) 151 return sortCols 152 }, 153 }, 154 { 155 name: "三个列顺序:降序,升序,降序", 156 nodes: func() []*node { 157 return newTestNodes([][]any{ 158 {2, "b", 1}, 159 {2, "a", 1}, 160 {2, "e", 2}, 161 {2, "e", 1}, 162 {2, "e", 3}, 163 {5, "b", 1}, 164 {5, "a", 1}, 165 {5, "e", 2}, 166 {5, "e", 1}, 167 {5, "e", 3}, 168 {1, "b", 1}, 169 {1, "a", 1}, 170 {1, "e", 2}, 171 {1, "e", 1}, 172 {1, "e", 3}, 173 }) 174 }, 175 wantNodes: func() []*node { 176 return newTestNodes([][]any{ 177 {5, "a", 1}, 178 {5, "b", 1}, 179 {5, "e", 3}, 180 {5, "e", 2}, 181 {5, "e", 1}, 182 {2, "a", 1}, 183 {2, "b", 1}, 184 {2, "e", 3}, 185 {2, "e", 2}, 186 {2, "e", 1}, 187 {1, "a", 1}, 188 {1, "b", 1}, 189 {1, "e", 3}, 190 {1, "e", 2}, 191 {1, "e", 1}, 192 }) 193 }, 194 sortCols: func() sortColumns { 195 sortCols, err := newSortColumns(NewSortColumn("id", DESC), NewSortColumn("name", ASC), NewSortColumn("age", DESC)) 196 require.NoError(t, err) 197 return sortCols 198 }, 199 }, 200 { 201 name: "三个列的顺序: 升序,升序,降序", 202 nodes: func() []*node { 203 return newTestNodes([][]any{ 204 {2, "b", 1}, 205 {2, "a", 1}, 206 {2, "e", 2}, 207 {2, "e", 1}, 208 {2, "e", 3}, 209 {5, "b", 1}, 210 {5, "a", 1}, 211 {5, "e", 2}, 212 {5, "e", 1}, 213 {5, "e", 3}, 214 {1, "b", 1}, 215 {1, "a", 1}, 216 {1, "e", 2}, 217 {1, "e", 1}, 218 {1, "e", 3}, 219 }) 220 }, 221 wantNodes: func() []*node { 222 return newTestNodes([][]any{ 223 {1, "a", 1}, 224 {1, "b", 1}, 225 {1, "e", 3}, 226 {1, "e", 2}, 227 {1, "e", 1}, 228 {2, "a", 1}, 229 {2, "b", 1}, 230 {2, "e", 3}, 231 {2, "e", 2}, 232 {2, "e", 1}, 233 {5, "a", 1}, 234 {5, "b", 1}, 235 {5, "e", 3}, 236 {5, "e", 2}, 237 {5, "e", 1}, 238 }) 239 }, 240 sortCols: func() sortColumns { 241 sortCols, err := newSortColumns(NewSortColumn("id", ASC), NewSortColumn("name", ASC), NewSortColumn("age", DESC)) 242 require.NoError(t, err) 243 return sortCols 244 }, 245 }, 246 { 247 name: "三个列的顺序: 降序,降序,升序", 248 nodes: func() []*node { 249 return newTestNodes([][]any{ 250 {2, "b", 1}, 251 {2, "a", 1}, 252 {2, "e", 2}, 253 {2, "e", 1}, 254 {2, "e", 3}, 255 {5, "b", 1}, 256 {5, "a", 1}, 257 {5, "e", 2}, 258 {5, "e", 1}, 259 {5, "e", 3}, 260 {1, "b", 1}, 261 {1, "a", 1}, 262 {1, "e", 2}, 263 {1, "e", 1}, 264 {1, "e", 3}, 265 }) 266 }, 267 wantNodes: func() []*node { 268 return newTestNodes([][]any{ 269 {5, "e", 1}, 270 {5, "e", 2}, 271 {5, "e", 3}, 272 {5, "b", 1}, 273 {5, "a", 1}, 274 {2, "e", 1}, 275 {2, "e", 2}, 276 {2, "e", 3}, 277 {2, "b", 1}, 278 {2, "a", 1}, 279 {1, "e", 1}, 280 {1, "e", 2}, 281 {1, "e", 3}, 282 {1, "b", 1}, 283 {1, "a", 1}, 284 }) 285 }, 286 sortCols: func() sortColumns { 287 sortCols, err := newSortColumns(NewSortColumn("id", DESC), NewSortColumn("name", DESC), NewSortColumn("age", ASC)) 288 require.NoError(t, err) 289 return sortCols 290 }, 291 }, 292 { 293 name: "三个列的顺序: 降序,降序,降序", 294 nodes: func() []*node { 295 return newTestNodes([][]any{ 296 {2, "b", 1}, 297 {2, "a", 1}, 298 {2, "e", 2}, 299 {2, "e", 1}, 300 {2, "e", 3}, 301 {5, "b", 1}, 302 {5, "a", 1}, 303 {5, "e", 2}, 304 {5, "e", 1}, 305 {5, "e", 3}, 306 {1, "b", 1}, 307 {1, "a", 1}, 308 {1, "e", 2}, 309 {1, "e", 1}, 310 {1, "e", 3}, 311 }) 312 }, 313 wantNodes: func() []*node { 314 return newTestNodes([][]any{ 315 {5, "e", 3}, 316 {5, "e", 2}, 317 {5, "e", 1}, 318 {5, "b", 1}, 319 {5, "a", 1}, 320 {2, "e", 3}, 321 {2, "e", 2}, 322 {2, "e", 1}, 323 {2, "b", 1}, 324 {2, "a", 1}, 325 {1, "e", 3}, 326 {1, "e", 2}, 327 {1, "e", 1}, 328 {1, "b", 1}, 329 {1, "a", 1}, 330 }) 331 }, 332 sortCols: func() sortColumns { 333 sortCols, err := newSortColumns(NewSortColumn("id", DESC), NewSortColumn("name", DESC), NewSortColumn("age", DESC)) 334 require.NoError(t, err) 335 return sortCols 336 }, 337 }, 338 { 339 name: "三个列的顺序: 升序,升序,升序", 340 nodes: func() []*node { 341 return newTestNodes([][]any{ 342 {2, "b", 1}, 343 {2, "a", 1}, 344 {2, "e", 2}, 345 {2, "e", 1}, 346 {2, "e", 3}, 347 {5, "b", 1}, 348 {5, "a", 1}, 349 {5, "e", 2}, 350 {5, "e", 1}, 351 {5, "e", 3}, 352 {1, "b", 1}, 353 {1, "a", 1}, 354 {1, "e", 2}, 355 {1, "e", 1}, 356 {1, "e", 3}, 357 }) 358 }, 359 wantNodes: func() []*node { 360 return newTestNodes([][]any{ 361 {1, "a", 1}, 362 {1, "b", 1}, 363 {1, "e", 1}, 364 {1, "e", 2}, 365 {1, "e", 3}, 366 {2, "a", 1}, 367 {2, "b", 1}, 368 {2, "e", 1}, 369 {2, "e", 2}, 370 {2, "e", 3}, 371 {5, "a", 1}, 372 {5, "b", 1}, 373 {5, "e", 1}, 374 {5, "e", 2}, 375 {5, "e", 3}, 376 }) 377 }, 378 sortCols: func() sortColumns { 379 sortCols, err := newSortColumns(NewSortColumn("id", ASC), NewSortColumn("name", ASC), NewSortColumn("age", ASC)) 380 require.NoError(t, err) 381 return sortCols 382 }, 383 }, 384 } 385 for _, tc := range testcases { 386 t.Run(tc.name, func(t *testing.T) { 387 h := newTestHp(tc.nodes(), tc.sortCols()) 388 res := make([]*node, 0, h.Len()) 389 for h.Len() > 0 { 390 res = append(res, heap.Pop(h).(*node)) 391 } 392 assert.Equal(t, tc.wantNodes(), res) 393 }) 394 } 395 396 } 397 398 func TestHeap_Nullable(t *testing.T) { 399 testcases := []struct { 400 name string 401 nodes func() []*node 402 wantNodes func() []*node 403 sortCols func() sortColumns 404 }{ 405 { 406 name: "sql.NullInt64 asc", 407 nodes: func() []*node { 408 return newTestNodes([][]any{ 409 {sql.NullInt64{Int64: 5, Valid: true}}, 410 {sql.NullInt64{Int64: 1, Valid: true}}, 411 {sql.NullInt64{Int64: 3, Valid: true}}, 412 {sql.NullInt64{Int64: 2, Valid: true}}, 413 {sql.NullInt64{Int64: 10, Valid: false}}, 414 }) 415 }, 416 wantNodes: func() []*node { 417 return newTestNodes([][]any{ 418 {sql.NullInt64{Int64: 10, Valid: false}}, 419 {sql.NullInt64{Int64: 1, Valid: true}}, 420 {sql.NullInt64{Int64: 2, Valid: true}}, 421 {sql.NullInt64{Int64: 3, Valid: true}}, 422 {sql.NullInt64{Int64: 5, Valid: true}}, 423 }) 424 }, 425 sortCols: func() sortColumns { 426 sortCols, err := newSortColumns(NewSortColumn("id", ASC)) 427 require.NoError(t, err) 428 return sortCols 429 }, 430 }, 431 { 432 name: "sql.NullInt64 desc", 433 nodes: func() []*node { 434 return newTestNodes([][]any{ 435 {sql.NullInt64{Int64: 5, Valid: true}}, 436 {sql.NullInt64{Int64: 1, Valid: true}}, 437 {sql.NullInt64{Int64: 3, Valid: true}}, 438 {sql.NullInt64{Int64: 2, Valid: true}}, 439 {sql.NullInt64{Int64: 10, Valid: false}}, 440 }) 441 }, 442 wantNodes: func() []*node { 443 return newTestNodes([][]any{ 444 {sql.NullInt64{Int64: 5, Valid: true}}, 445 {sql.NullInt64{Int64: 3, Valid: true}}, 446 {sql.NullInt64{Int64: 2, Valid: true}}, 447 {sql.NullInt64{Int64: 1, Valid: true}}, 448 {sql.NullInt64{Int64: 10, Valid: false}}, 449 }) 450 }, 451 sortCols: func() sortColumns { 452 sortCols, err := newSortColumns(NewSortColumn("id", DESC)) 453 require.NoError(t, err) 454 return sortCols 455 }, 456 }, 457 { 458 name: "sql.NullString asc", 459 nodes: func() []*node { 460 return newTestNodes([][]any{ 461 {sql.NullString{String: "ab", Valid: true}}, 462 {sql.NullString{String: "cd", Valid: true}}, 463 {sql.NullString{String: "bc", Valid: true}}, 464 {sql.NullString{String: "ba", Valid: true}}, 465 {sql.NullString{String: "z", Valid: false}}, 466 }) 467 }, 468 wantNodes: func() []*node { 469 return newTestNodes([][]any{ 470 {sql.NullString{String: "z", Valid: false}}, 471 {sql.NullString{String: "ab", Valid: true}}, 472 {sql.NullString{String: "ba", Valid: true}}, 473 {sql.NullString{String: "bc", Valid: true}}, 474 {sql.NullString{String: "cd", Valid: true}}, 475 }) 476 }, 477 sortCols: func() sortColumns { 478 sortCols, err := newSortColumns(NewSortColumn("name", ASC)) 479 require.NoError(t, err) 480 return sortCols 481 }, 482 }, 483 { 484 name: "sql.NullString desc", 485 nodes: func() []*node { 486 return newTestNodes([][]any{ 487 {sql.NullString{String: "ab", Valid: true}}, 488 {sql.NullString{String: "cd", Valid: true}}, 489 {sql.NullString{String: "bc", Valid: true}}, 490 {sql.NullString{String: "z", Valid: false}}, 491 {sql.NullString{String: "ba", Valid: true}}, 492 }) 493 }, 494 wantNodes: func() []*node { 495 return newTestNodes([][]any{ 496 {sql.NullString{String: "cd", Valid: true}}, 497 {sql.NullString{String: "bc", Valid: true}}, 498 {sql.NullString{String: "ba", Valid: true}}, 499 {sql.NullString{String: "ab", Valid: true}}, 500 {sql.NullString{String: "z", Valid: false}}, 501 }) 502 }, 503 sortCols: func() sortColumns { 504 sortCols, err := newSortColumns(NewSortColumn("name", DESC)) 505 require.NoError(t, err) 506 return sortCols 507 }, 508 }, 509 { 510 name: "sql.NullInt16 asc", 511 nodes: func() []*node { 512 return newTestNodes([][]any{ 513 {sql.NullInt16{Int16: 5, Valid: true}}, 514 {sql.NullInt16{Int16: 1, Valid: true}}, 515 {sql.NullInt16{Int16: 3, Valid: true}}, 516 {sql.NullInt16{Int16: 2, Valid: true}}, 517 {sql.NullInt16{Int16: 10, Valid: false}}, 518 }) 519 }, 520 wantNodes: func() []*node { 521 return newTestNodes([][]any{ 522 {sql.NullInt16{Int16: 10, Valid: false}}, 523 {sql.NullInt16{Int16: 1, Valid: true}}, 524 {sql.NullInt16{Int16: 2, Valid: true}}, 525 {sql.NullInt16{Int16: 3, Valid: true}}, 526 {sql.NullInt16{Int16: 5, Valid: true}}, 527 }) 528 }, 529 sortCols: func() sortColumns { 530 sortCols, err := newSortColumns(NewSortColumn("id", ASC)) 531 require.NoError(t, err) 532 return sortCols 533 }, 534 }, 535 { 536 name: "sql.NullInt16 desc", 537 nodes: func() []*node { 538 return newTestNodes([][]any{ 539 {sql.NullInt16{Int16: 5, Valid: true}}, 540 {sql.NullInt16{Int16: 1, Valid: true}}, 541 {sql.NullInt16{Int16: 3, Valid: true}}, 542 {sql.NullInt16{Int16: 2, Valid: true}}, 543 {sql.NullInt16{Int16: 10, Valid: false}}, 544 }) 545 }, 546 wantNodes: func() []*node { 547 return newTestNodes([][]any{ 548 {sql.NullInt16{Int16: 5, Valid: true}}, 549 {sql.NullInt16{Int16: 3, Valid: true}}, 550 {sql.NullInt16{Int16: 2, Valid: true}}, 551 {sql.NullInt16{Int16: 1, Valid: true}}, 552 {sql.NullInt16{Int16: 10, Valid: false}}, 553 }) 554 }, 555 sortCols: func() sortColumns { 556 sortCols, err := newSortColumns(NewSortColumn("id", DESC)) 557 require.NoError(t, err) 558 return sortCols 559 }, 560 }, 561 { 562 name: "sql.NullInt32 asc", 563 nodes: func() []*node { 564 return newTestNodes([][]any{ 565 {sql.NullInt32{Int32: 5, Valid: true}}, 566 {sql.NullInt32{Int32: 1, Valid: true}}, 567 {sql.NullInt32{Int32: 3, Valid: true}}, 568 {sql.NullInt32{Int32: 2, Valid: true}}, 569 {sql.NullInt32{Int32: 10, Valid: false}}, 570 }) 571 }, 572 wantNodes: func() []*node { 573 return newTestNodes([][]any{ 574 {sql.NullInt32{Int32: 10, Valid: false}}, 575 {sql.NullInt32{Int32: 1, Valid: true}}, 576 {sql.NullInt32{Int32: 2, Valid: true}}, 577 {sql.NullInt32{Int32: 3, Valid: true}}, 578 {sql.NullInt32{Int32: 5, Valid: true}}, 579 }) 580 }, 581 sortCols: func() sortColumns { 582 sortCols, err := newSortColumns(NewSortColumn("id", ASC)) 583 require.NoError(t, err) 584 return sortCols 585 }, 586 }, 587 { 588 name: "sql.NullInt32 desc", 589 nodes: func() []*node { 590 return newTestNodes([][]any{ 591 {sql.NullInt32{Int32: 5, Valid: true}}, 592 {sql.NullInt32{Int32: 1, Valid: true}}, 593 {sql.NullInt32{Int32: 3, Valid: true}}, 594 {sql.NullInt32{Int32: 2, Valid: true}}, 595 {sql.NullInt32{Int32: 10, Valid: false}}, 596 }) 597 }, 598 wantNodes: func() []*node { 599 return newTestNodes([][]any{ 600 {sql.NullInt32{Int32: 5, Valid: true}}, 601 {sql.NullInt32{Int32: 3, Valid: true}}, 602 {sql.NullInt32{Int32: 2, Valid: true}}, 603 {sql.NullInt32{Int32: 1, Valid: true}}, 604 {sql.NullInt32{Int32: 10, Valid: false}}, 605 }) 606 }, 607 sortCols: func() sortColumns { 608 sortCols, err := newSortColumns(NewSortColumn("id", DESC)) 609 require.NoError(t, err) 610 return sortCols 611 }, 612 }, 613 { 614 name: "sql.NullFloat64 asc", 615 nodes: func() []*node { 616 return newTestNodes([][]any{ 617 {sql.NullFloat64{Float64: 5.0, Valid: true}}, 618 {sql.NullFloat64{Float64: 1.0, Valid: true}}, 619 {sql.NullFloat64{Float64: 3.0, Valid: true}}, 620 {sql.NullFloat64{Float64: 2.0, Valid: true}}, 621 {sql.NullFloat64{Float64: 10.0, Valid: false}}, 622 }) 623 }, 624 wantNodes: func() []*node { 625 return newTestNodes([][]any{ 626 {sql.NullFloat64{Float64: 10.0, Valid: false}}, 627 {sql.NullFloat64{Float64: 1.0, Valid: true}}, 628 {sql.NullFloat64{Float64: 2.0, Valid: true}}, 629 {sql.NullFloat64{Float64: 3.0, Valid: true}}, 630 {sql.NullFloat64{Float64: 5.0, Valid: true}}, 631 }) 632 }, 633 sortCols: func() sortColumns { 634 sortCols, err := newSortColumns(NewSortColumn("id", ASC)) 635 require.NoError(t, err) 636 return sortCols 637 }, 638 }, 639 { 640 name: "sql.NullFloat64 desc", 641 nodes: func() []*node { 642 return newTestNodes([][]any{ 643 {sql.NullFloat64{Float64: 5.0, Valid: true}}, 644 {sql.NullFloat64{Float64: 1.0, Valid: true}}, 645 {sql.NullFloat64{Float64: 3.0, Valid: true}}, 646 {sql.NullFloat64{Float64: 2.0, Valid: true}}, 647 {sql.NullFloat64{Float64: 10.0, Valid: false}}, 648 }) 649 }, 650 wantNodes: func() []*node { 651 return newTestNodes([][]any{ 652 {sql.NullFloat64{Float64: 5.0, Valid: true}}, 653 {sql.NullFloat64{Float64: 3.0, Valid: true}}, 654 {sql.NullFloat64{Float64: 2.0, Valid: true}}, 655 {sql.NullFloat64{Float64: 1.0, Valid: true}}, 656 {sql.NullFloat64{Float64: 10.0, Valid: false}}, 657 }) 658 }, 659 sortCols: func() sortColumns { 660 sortCols, err := newSortColumns(NewSortColumn("id", DESC)) 661 require.NoError(t, err) 662 return sortCols 663 }, 664 }, 665 666 { 667 name: "sql.NullTime asc", 668 nodes: func() []*node { 669 return newTestNodes([][]any{ 670 {sql.NullTime{Time: func() time.Time { 671 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 12:00:00", time.Local) 672 require.NoError(t, err) 673 return time 674 }(), Valid: true}}, 675 {sql.NullTime{Time: func() time.Time { 676 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-02 12:00:00", time.Local) 677 require.NoError(t, err) 678 return time 679 }(), Valid: true}}, 680 {sql.NullTime{Time: func() time.Time { 681 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-09 12:00:00", time.Local) 682 require.NoError(t, err) 683 return time 684 }(), Valid: true}}, 685 {sql.NullTime{Time: func() time.Time { 686 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 11:00:00", time.Local) 687 require.NoError(t, err) 688 return time 689 }(), Valid: true}}, 690 {sql.NullTime{Time: func() time.Time { 691 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-20 12:00:00", time.Local) 692 require.NoError(t, err) 693 return time 694 }(), Valid: false}}, 695 }) 696 }, 697 wantNodes: func() []*node { 698 return newTestNodes([][]any{ 699 {sql.NullTime{Time: func() time.Time { 700 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-20 12:00:00", time.Local) 701 require.NoError(t, err) 702 return time 703 }(), Valid: false}}, 704 {sql.NullTime{Time: func() time.Time { 705 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 11:00:00", time.Local) 706 require.NoError(t, err) 707 return time 708 }(), Valid: true}}, 709 {sql.NullTime{Time: func() time.Time { 710 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 12:00:00", time.Local) 711 require.NoError(t, err) 712 return time 713 }(), Valid: true}}, 714 {sql.NullTime{Time: func() time.Time { 715 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-02 12:00:00", time.Local) 716 require.NoError(t, err) 717 return time 718 }(), Valid: true}}, 719 {sql.NullTime{Time: func() time.Time { 720 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-09 12:00:00", time.Local) 721 require.NoError(t, err) 722 return time 723 }(), Valid: true}}, 724 }) 725 }, 726 sortCols: func() sortColumns { 727 sortCols, err := newSortColumns(NewSortColumn("time", ASC)) 728 require.NoError(t, err) 729 return sortCols 730 }, 731 }, 732 { 733 name: "sql.NullTime desc", 734 nodes: func() []*node { 735 return newTestNodes([][]any{ 736 {sql.NullTime{Time: func() time.Time { 737 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 12:00:00", time.Local) 738 require.NoError(t, err) 739 return time 740 }(), Valid: true}}, 741 {sql.NullTime{Time: func() time.Time { 742 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-02 12:00:00", time.Local) 743 require.NoError(t, err) 744 return time 745 }(), Valid: true}}, 746 {sql.NullTime{Time: func() time.Time { 747 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-09 12:00:00", time.Local) 748 require.NoError(t, err) 749 return time 750 }(), Valid: true}}, 751 {sql.NullTime{Time: func() time.Time { 752 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 11:00:00", time.Local) 753 require.NoError(t, err) 754 return time 755 }(), Valid: true}}, 756 {sql.NullTime{Time: func() time.Time { 757 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-20 12:00:00", time.Local) 758 require.NoError(t, err) 759 return time 760 }(), Valid: false}}, 761 }) 762 }, 763 wantNodes: func() []*node { 764 return newTestNodes([][]any{ 765 {sql.NullTime{Time: func() time.Time { 766 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-09 12:00:00", time.Local) 767 require.NoError(t, err) 768 return time 769 }(), Valid: true}}, 770 {sql.NullTime{Time: func() time.Time { 771 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-02 12:00:00", time.Local) 772 require.NoError(t, err) 773 return time 774 }(), Valid: true}}, 775 {sql.NullTime{Time: func() time.Time { 776 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 12:00:00", time.Local) 777 require.NoError(t, err) 778 return time 779 }(), Valid: true}}, 780 {sql.NullTime{Time: func() time.Time { 781 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-01 11:00:00", time.Local) 782 require.NoError(t, err) 783 return time 784 }(), Valid: true}}, 785 {sql.NullTime{Time: func() time.Time { 786 time, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-01-20 12:00:00", time.Local) 787 require.NoError(t, err) 788 return time 789 }(), Valid: false}}, 790 }) 791 }, 792 sortCols: func() sortColumns { 793 sortCols, err := newSortColumns(NewSortColumn("time", DESC)) 794 require.NoError(t, err) 795 return sortCols 796 }, 797 }, 798 { 799 name: "sql.NullByte asc", 800 nodes: func() []*node { 801 return newTestNodes([][]any{ 802 {sql.NullByte{Byte: 'a', Valid: true}}, 803 {sql.NullByte{Byte: 'c', Valid: true}}, 804 {sql.NullByte{Byte: 'b', Valid: true}}, 805 {sql.NullByte{Byte: 'k', Valid: true}}, 806 {sql.NullByte{Byte: 'z', Valid: false}}, 807 }) 808 }, 809 wantNodes: func() []*node { 810 return newTestNodes([][]any{ 811 {sql.NullByte{Byte: 'z', Valid: false}}, 812 {sql.NullByte{Byte: 'a', Valid: true}}, 813 {sql.NullByte{Byte: 'b', Valid: true}}, 814 {sql.NullByte{Byte: 'c', Valid: true}}, 815 {sql.NullByte{Byte: 'k', Valid: true}}, 816 }) 817 }, 818 sortCols: func() sortColumns { 819 sortCols, err := newSortColumns(NewSortColumn("byte", ASC)) 820 require.NoError(t, err) 821 return sortCols 822 }, 823 }, 824 { 825 name: "sql.NullByte desc", 826 nodes: func() []*node { 827 return newTestNodes([][]any{ 828 {sql.NullByte{Byte: 'a', Valid: true}}, 829 {sql.NullByte{Byte: 'c', Valid: true}}, 830 {sql.NullByte{Byte: 'b', Valid: true}}, 831 {sql.NullByte{Byte: 'k', Valid: true}}, 832 {sql.NullByte{Byte: 'z', Valid: false}}, 833 }) 834 }, 835 wantNodes: func() []*node { 836 return newTestNodes([][]any{ 837 {sql.NullByte{Byte: 'k', Valid: true}}, 838 {sql.NullByte{Byte: 'c', Valid: true}}, 839 {sql.NullByte{Byte: 'b', Valid: true}}, 840 {sql.NullByte{Byte: 'a', Valid: true}}, 841 {sql.NullByte{Byte: 'z', Valid: false}}, 842 }) 843 }, 844 sortCols: func() sortColumns { 845 sortCols, err := newSortColumns(NewSortColumn("byte", DESC)) 846 require.NoError(t, err) 847 return sortCols 848 }, 849 }, 850 } 851 for _, tc := range testcases { 852 t.Run(tc.name, func(t *testing.T) { 853 h := newTestHp(tc.nodes(), tc.sortCols()) 854 res := make([]*node, 0, h.Len()) 855 for h.Len() > 0 { 856 res = append(res, heap.Pop(h).(*node)) 857 } 858 assert.Equal(t, tc.wantNodes(), res) 859 }) 860 } 861 } 862 863 func (ms *MergerSuite) TestCompare() { 864 testcases := []struct { 865 name string 866 values []any 867 order Order 868 wantVal int 869 kind reflect.Kind 870 }{ 871 { 872 name: "int8 ASC 1,2", 873 values: []any{int8(1), int8(2)}, 874 order: ASC, 875 wantVal: -1, 876 kind: reflect.Int8, 877 }, 878 { 879 name: "int8 DESC 1,2", 880 values: []any{int8(1), int8(2)}, 881 order: DESC, 882 wantVal: 1, 883 kind: reflect.Int8, 884 }, 885 { 886 name: "int8 ASC 2,1", 887 values: []any{int8(2), int8(1)}, 888 order: ASC, 889 wantVal: 1, 890 kind: reflect.Int8, 891 }, 892 { 893 name: "int8 DESC 2,1", 894 values: []any{int8(2), int8(1)}, 895 order: DESC, 896 wantVal: -1, 897 kind: reflect.Int8, 898 }, 899 { 900 name: "int8 equal", 901 values: []any{int8(2), int8(2)}, 902 order: DESC, 903 wantVal: 0, 904 kind: reflect.Int8, 905 }, 906 { 907 name: "int16 ASC 1,2", 908 values: []any{int16(1), int16(2)}, 909 order: ASC, 910 wantVal: -1, 911 kind: reflect.Int16, 912 }, 913 { 914 name: "int16 DESC 1,2", 915 values: []any{int16(1), int16(2)}, 916 order: DESC, 917 wantVal: 1, 918 kind: reflect.Int16, 919 }, 920 { 921 name: "int16 ASC 2,1", 922 values: []any{int16(2), int16(1)}, 923 order: ASC, 924 wantVal: 1, 925 kind: reflect.Int16, 926 }, 927 { 928 name: "int16 DESC 2,1", 929 values: []any{int16(2), int16(1)}, 930 order: DESC, 931 wantVal: -1, 932 kind: reflect.Int16, 933 }, 934 { 935 name: "int16 equa", 936 values: []any{int16(2), int16(2)}, 937 order: DESC, 938 wantVal: 0, 939 kind: reflect.Int16, 940 }, 941 { 942 name: "int32 ASC 1,2", 943 values: []any{int32(1), int32(2)}, 944 order: ASC, 945 wantVal: -1, 946 kind: reflect.Int32, 947 }, 948 { 949 name: "int32 DESC 1,2", 950 values: []any{int32(1), int32(2)}, 951 order: DESC, 952 wantVal: 1, 953 kind: reflect.Int32, 954 }, 955 { 956 name: "int32 ASC 2,1", 957 values: []any{int32(2), int32(1)}, 958 order: ASC, 959 wantVal: 1, 960 kind: reflect.Int32, 961 }, 962 { 963 name: "int32 DESC 2,1", 964 values: []any{int32(2), int32(1)}, 965 order: DESC, 966 wantVal: -1, 967 kind: reflect.Int32, 968 }, 969 { 970 name: "int32 equal", 971 values: []any{int32(2), int32(2)}, 972 order: DESC, 973 wantVal: 0, 974 kind: reflect.Int32, 975 }, 976 { 977 name: "int64 ASC 1,2", 978 values: []any{int64(1), int64(02)}, 979 order: ASC, 980 wantVal: -1, 981 kind: reflect.Int64, 982 }, 983 { 984 name: "int64 DESC 1,2", 985 values: []any{int64(1), int64(2)}, 986 order: DESC, 987 wantVal: 1, 988 kind: reflect.Int64, 989 }, 990 { 991 name: "int64 ASC 2,1", 992 values: []any{int64(2), int64(1)}, 993 order: ASC, 994 wantVal: 1, 995 kind: reflect.Int64, 996 }, 997 { 998 name: "int64 DESC 2,1", 999 values: []any{int64(2), int64(1)}, 1000 order: DESC, 1001 wantVal: -1, 1002 kind: reflect.Int64, 1003 }, 1004 { 1005 name: "int64 equal", 1006 values: []any{int64(2), int64(2)}, 1007 order: DESC, 1008 wantVal: 0, 1009 kind: reflect.Int64, 1010 }, 1011 { 1012 name: "uint8 ASC 1,2", 1013 values: []any{uint8(1), uint8(2)}, 1014 order: ASC, 1015 wantVal: -1, 1016 kind: reflect.Uint8, 1017 }, 1018 { 1019 name: "uint8 DESC 1,2", 1020 values: []any{uint8(1), uint8(2)}, 1021 order: DESC, 1022 wantVal: 1, 1023 kind: reflect.Uint8, 1024 }, 1025 { 1026 name: "uint8 ASC 2,1", 1027 values: []any{uint8(2), uint8(1)}, 1028 order: ASC, 1029 wantVal: 1, 1030 kind: reflect.Uint8, 1031 }, 1032 { 1033 name: "uint8 DESC 2,1", 1034 values: []any{uint8(2), uint8(1)}, 1035 order: DESC, 1036 wantVal: -1, 1037 kind: reflect.Uint8, 1038 }, 1039 { 1040 name: "uint8 equal", 1041 values: []any{uint8(2), uint8(2)}, 1042 order: DESC, 1043 wantVal: 0, 1044 kind: reflect.Uint8, 1045 }, 1046 1047 { 1048 name: "uint16 ASC 1,2", 1049 values: []any{uint16(1), uint16(2)}, 1050 order: ASC, 1051 wantVal: -1, 1052 kind: reflect.Uint16, 1053 }, 1054 { 1055 name: "uint16 DESC 1,2", 1056 values: []any{uint16(1), uint16(2)}, 1057 order: DESC, 1058 wantVal: 1, 1059 kind: reflect.Uint16, 1060 }, 1061 { 1062 name: "uint16 ASC 2,1", 1063 values: []any{uint16(2), uint16(1)}, 1064 order: ASC, 1065 wantVal: 1, 1066 kind: reflect.Uint16, 1067 }, 1068 { 1069 name: "uint16 DESC 2,1", 1070 values: []any{uint16(2), uint16(1)}, 1071 order: DESC, 1072 wantVal: -1, 1073 kind: reflect.Uint16, 1074 }, 1075 { 1076 name: "uint16 equal", 1077 values: []any{uint16(2), uint16(2)}, 1078 order: DESC, 1079 wantVal: 0, 1080 kind: reflect.Uint16, 1081 }, 1082 { 1083 name: "uint32 ASC 1,2", 1084 values: []any{uint32(1), uint32(2)}, 1085 order: ASC, 1086 wantVal: -1, 1087 kind: reflect.Uint32, 1088 }, 1089 { 1090 name: "uint32 DESC 1,2", 1091 values: []any{uint32(1), uint32(2)}, 1092 order: DESC, 1093 wantVal: 1, 1094 kind: reflect.Uint32, 1095 }, 1096 { 1097 name: "uint32 ASC 2,1", 1098 values: []any{uint32(2), uint32(1)}, 1099 order: ASC, 1100 wantVal: 1, 1101 kind: reflect.Uint32, 1102 }, 1103 { 1104 name: "uint32 DESC 2,1", 1105 values: []any{uint32(2), uint32(1)}, 1106 order: DESC, 1107 wantVal: -1, 1108 kind: reflect.Uint32, 1109 }, 1110 { 1111 name: "uint32 equal", 1112 values: []any{uint32(2), uint32(2)}, 1113 order: DESC, 1114 wantVal: 0, 1115 kind: reflect.Uint32, 1116 }, 1117 { 1118 name: "uint64 ASC 1,2", 1119 values: []any{uint64(1), uint64(2)}, 1120 order: ASC, 1121 wantVal: -1, 1122 kind: reflect.Uint64, 1123 }, 1124 { 1125 name: "uint64 DESC 1,2", 1126 values: []any{uint64(1), uint64(2)}, 1127 order: DESC, 1128 wantVal: 1, 1129 kind: reflect.Uint64, 1130 }, 1131 { 1132 name: "uint64 ASC 2,1", 1133 values: []any{uint64(2), uint64(1)}, 1134 order: ASC, 1135 wantVal: 1, 1136 kind: reflect.Uint64, 1137 }, 1138 { 1139 name: "uint64 DESC 2,1", 1140 values: []any{uint64(2), uint64(1)}, 1141 order: DESC, 1142 wantVal: -1, 1143 kind: reflect.Uint64, 1144 }, 1145 { 1146 name: "uint64 equal", 1147 values: []any{uint64(2), uint64(2)}, 1148 order: DESC, 1149 wantVal: 0, 1150 kind: reflect.Uint64, 1151 }, 1152 { 1153 name: "float32 ASC 1,2", 1154 values: []any{float32(1.1), float32(2.1)}, 1155 order: ASC, 1156 wantVal: -1, 1157 kind: reflect.Float32, 1158 }, 1159 { 1160 name: "float32 DESC 1,2", 1161 values: []any{float32(1.1), float32(2.1)}, 1162 order: DESC, 1163 wantVal: 1, 1164 kind: reflect.Float32, 1165 }, 1166 { 1167 name: "float32 ASC 2,1", 1168 values: []any{float32(2), float32(1)}, 1169 order: ASC, 1170 wantVal: 1, 1171 kind: reflect.Float32, 1172 }, 1173 { 1174 name: "float32 DESC 2,1", 1175 values: []any{float32(2.1), float32(1.1)}, 1176 order: DESC, 1177 wantVal: -1, 1178 kind: reflect.Float32, 1179 }, 1180 { 1181 name: "float32 equal", 1182 values: []any{float32(2.1), float32(2.1)}, 1183 order: DESC, 1184 wantVal: 0, 1185 kind: reflect.Float32, 1186 }, 1187 { 1188 name: "float64 ASC 1,2", 1189 values: []any{float64(1.1), float64(2.1)}, 1190 order: ASC, 1191 wantVal: -1, 1192 kind: reflect.Float64, 1193 }, 1194 { 1195 name: "float64 DESC 1,2", 1196 values: []any{float64(1), float64(2)}, 1197 order: DESC, 1198 wantVal: 1, 1199 kind: reflect.Float64, 1200 }, 1201 { 1202 name: "float64 ASC 2,1", 1203 values: []any{float64(2), float64(1)}, 1204 order: ASC, 1205 wantVal: 1, 1206 kind: reflect.Float64, 1207 }, 1208 { 1209 name: "float64 DESC 2,1", 1210 values: []any{float64(2.1), float64(1.1)}, 1211 order: DESC, 1212 wantVal: -1, 1213 kind: reflect.Float64, 1214 }, 1215 { 1216 name: "float64 equal", 1217 values: []any{float64(2.1), float64(2.1)}, 1218 order: DESC, 1219 wantVal: 0, 1220 kind: reflect.Float64, 1221 }, 1222 { 1223 name: "string equal", 1224 values: []any{"x", "x"}, 1225 order: DESC, 1226 wantVal: 0, 1227 kind: reflect.String, 1228 }, 1229 } 1230 for _, tc := range testcases { 1231 ms.T().Run(tc.name, func(t *testing.T) { 1232 cmp, ok := compareFuncMapping[tc.kind] 1233 require.True(t, ok) 1234 val := cmp(tc.values[0], tc.values[1], tc.order) 1235 assert.Equal(t, tc.wantVal, val) 1236 }) 1237 } 1238 }