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  }