github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/setalgebra/intersection_test.go (about)

     1  // Copyright 2020 Dolthub, Inc.
     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 setalgebra
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  
    23  	"github.com/dolthub/dolt/go/store/hash"
    24  	"github.com/dolthub/dolt/go/store/types"
    25  )
    26  
    27  func TestFiniteSetIntersection(t *testing.T) {
    28  	tests := []struct {
    29  		name      string
    30  		setVals1  []types.Value
    31  		setVals2  []types.Value
    32  		expected  Set
    33  		expectErr bool
    34  	}{
    35  		{
    36  			"empty finite set",
    37  			[]types.Value{},
    38  			[]types.Value{},
    39  			EmptySet{},
    40  			false,
    41  		},
    42  		{
    43  			"non overlapping",
    44  			[]types.Value{types.Int(1), types.Int(2)},
    45  			[]types.Value{types.Int(3), types.Int(4)},
    46  			EmptySet{},
    47  			false,
    48  		},
    49  		{
    50  			"some overlapping",
    51  			[]types.Value{types.Int(1), types.Int(2)},
    52  			[]types.Value{types.Int(2), types.Int(3)},
    53  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(2))),
    54  			false,
    55  		},
    56  	}
    57  
    58  	for _, test := range tests {
    59  		t.Run(test.name, func(t *testing.T) {
    60  			fs1, err := NewFiniteSet(types.Format_Default, test.setVals1...)
    61  			require.NoError(t, err)
    62  
    63  			fs2, err := NewFiniteSet(types.Format_Default, test.setVals2...)
    64  			require.NoError(t, err)
    65  
    66  			res, err := finiteSetIntersection(fs1, fs2)
    67  			assertErr(t, test.expectErr, err)
    68  
    69  			assert.Equal(t, test.expected, res)
    70  		})
    71  	}
    72  }
    73  
    74  func TestFiniteSetIntervalIntersection(t *testing.T) {
    75  	tests := []struct {
    76  		name      string
    77  		setVals   []types.Value
    78  		in        Interval
    79  		expected  Set
    80  		expectErr bool
    81  	}{
    82  		{
    83  			"interval contains set",
    84  			[]types.Value{types.Int(0), types.Int(5), types.Int(10)},
    85  			Interval{
    86  				types.Format_Default,
    87  				&IntervalEndpoint{types.Int(0), true},
    88  				&IntervalEndpoint{types.Int(10), true},
    89  			},
    90  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(5), types.Int(10))),
    91  			false,
    92  		},
    93  		{
    94  			"some of set outside interval",
    95  			[]types.Value{types.Int(-5), types.Int(0), types.Int(5), types.Int(20)},
    96  			Interval{
    97  				types.Format_Default,
    98  				&IntervalEndpoint{types.Int(0), true},
    99  				&IntervalEndpoint{types.Int(10), true},
   100  			},
   101  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(5))),
   102  			false,
   103  		},
   104  		{
   105  			"open intervals",
   106  			[]types.Value{types.Int(0), types.Int(5), types.Int(10)},
   107  			Interval{
   108  				types.Format_Default,
   109  				&IntervalEndpoint{types.Int(0), false},
   110  				&IntervalEndpoint{types.Int(10), false},
   111  			},
   112  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(5))),
   113  			false,
   114  		},
   115  		{
   116  			"negative infinity",
   117  			[]types.Value{types.Int(0), types.Int(5), types.Int(10)},
   118  			Interval{
   119  				types.Format_Default,
   120  				nil,
   121  				&IntervalEndpoint{types.Int(10), true},
   122  			},
   123  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(5), types.Int(10))),
   124  			false,
   125  		},
   126  		{
   127  			"positive infinity",
   128  			[]types.Value{types.Int(0), types.Int(5), types.Int(10)},
   129  			Interval{
   130  				types.Format_Default,
   131  				&IntervalEndpoint{types.Int(0), false},
   132  				nil,
   133  			},
   134  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(5), types.Int(10))),
   135  			false,
   136  		},
   137  		{
   138  			"negative to positive infinity",
   139  			[]types.Value{types.Int(0), types.Int(5), types.Int(10)},
   140  			Interval{
   141  				types.Format_Default,
   142  				nil,
   143  				nil,
   144  			},
   145  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(5), types.Int(10))),
   146  			false,
   147  		},
   148  	}
   149  
   150  	for _, test := range tests {
   151  		t.Run(test.name, func(t *testing.T) {
   152  			fs, err := NewFiniteSet(types.Format_Default, test.setVals...)
   153  			require.NoError(t, err)
   154  
   155  			res, err := finiteSetIntervalIntersection(fs, test.in)
   156  			assert.NoError(t, err)
   157  
   158  			assert.Equal(t, test.expected, res)
   159  		})
   160  	}
   161  }
   162  
   163  func TestFiniteSetCompositeSetIntersection(t *testing.T) {
   164  	tests := []struct {
   165  		name      string
   166  		setVals   []types.Value
   167  		cs        CompositeSet
   168  		expected  Set
   169  		expectErr bool
   170  	}{
   171  		/*{
   172  			"empty set",
   173  			[]types.Value{},
   174  			CompositeSet{
   175  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(20))),
   176  				[]Interval{
   177  					{
   178  						types.Format_Default,
   179  						&IntervalEndpoint{types.Int(0), true},
   180  						&IntervalEndpoint{types.Int(10), true},
   181  					},
   182  				},
   183  			},
   184  			EmptySet{},
   185  			false,
   186  		},
   187  		{
   188  			"set with contained and uncontained vals",
   189  			[]types.Value{types.Int(-10), types.Int(0), types.Int(10), types.Int(20), types.Int(30)},
   190  			CompositeSet{
   191  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(20))),
   192  				[]Interval{
   193  					{
   194  						types.Format_Default,
   195  						&IntervalEndpoint{types.Int(0), true},
   196  						&IntervalEndpoint{types.Int(10), true},
   197  					},
   198  				},
   199  			},
   200  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(10), types.Int(20))),
   201  			false,
   202  		},*/
   203  		{
   204  			"composite set with multiple intervals",
   205  			[]types.Value{types.Int(-10), types.Int(0), types.Int(10), types.Int(20), types.Int(30), types.Int(99), types.Int(100), types.Int(0x7FFFFFFFFFFFFFFF)},
   206  			CompositeSet{
   207  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(20))),
   208  				[]Interval{
   209  					{
   210  						types.Format_Default,
   211  						&IntervalEndpoint{types.Int(0), true},
   212  						&IntervalEndpoint{types.Int(10), true},
   213  					},
   214  					{
   215  						types.Format_Default,
   216  						&IntervalEndpoint{types.Int(100), true},
   217  						nil,
   218  					},
   219  				},
   220  			},
   221  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(10), types.Int(20), types.Int(100), types.Int(0x7FFFFFFFFFFFFFFF))),
   222  			false,
   223  		},
   224  	}
   225  
   226  	for _, test := range tests {
   227  		t.Run(test.name, func(t *testing.T) {
   228  			fs, err := NewFiniteSet(types.Format_Default, test.setVals...)
   229  			require.NoError(t, err)
   230  
   231  			res, err := finiteSetCompositeSetIntersection(fs, test.cs)
   232  			assert.NoError(t, err)
   233  
   234  			assert.Equal(t, test.expected, res)
   235  		})
   236  	}
   237  }
   238  
   239  func TestIntersectIntervalWithStartPoints(t *testing.T) {
   240  	tests := []struct {
   241  		name      string
   242  		in        Interval
   243  		in2       Interval
   244  		expected  Set
   245  		expectErr bool
   246  	}{
   247  		{
   248  			"No overlap",
   249  			Interval{
   250  				types.Format_Default,
   251  				&IntervalEndpoint{types.Int(0), true},
   252  				&IntervalEndpoint{types.Int(10), false},
   253  			},
   254  			Interval{
   255  				types.Format_Default,
   256  				&IntervalEndpoint{types.Int(10), false},
   257  				&IntervalEndpoint{types.Int(20), true},
   258  			},
   259  			EmptySet{},
   260  			false,
   261  		},
   262  		{
   263  			"overlap at endpoints",
   264  			Interval{
   265  				types.Format_Default,
   266  				&IntervalEndpoint{types.Int(0), true},
   267  				&IntervalEndpoint{types.Int(10), true},
   268  			},
   269  			Interval{
   270  				types.Format_Default,
   271  				&IntervalEndpoint{types.Int(10), true},
   272  				&IntervalEndpoint{types.Int(20), true},
   273  			},
   274  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10))),
   275  			false,
   276  		},
   277  		{
   278  			"1 fully enclosed in 2",
   279  			Interval{
   280  				types.Format_Default,
   281  				&IntervalEndpoint{types.Int(5), true},
   282  				&IntervalEndpoint{types.Int(15), false},
   283  			},
   284  			Interval{
   285  				types.Format_Default,
   286  				&IntervalEndpoint{types.Int(0), true},
   287  				&IntervalEndpoint{types.Int(20), true},
   288  			},
   289  			Interval{
   290  				types.Format_Default,
   291  				&IntervalEndpoint{types.Int(5), true},
   292  				&IntervalEndpoint{types.Int(15), false},
   293  			},
   294  			false,
   295  		},
   296  		{
   297  			"2 fully enclosed 1",
   298  			Interval{
   299  				types.Format_Default,
   300  				&IntervalEndpoint{types.Int(0), true},
   301  				&IntervalEndpoint{types.Int(20), true},
   302  			},
   303  			Interval{
   304  				types.Format_Default,
   305  				&IntervalEndpoint{types.Int(5), true},
   306  				&IntervalEndpoint{types.Int(15), false},
   307  			},
   308  			Interval{
   309  				types.Format_Default,
   310  				&IntervalEndpoint{types.Int(5), true},
   311  				&IntervalEndpoint{types.Int(15), false},
   312  			},
   313  			false,
   314  		},
   315  		{
   316  			"intersect open and closed endpoints",
   317  			Interval{
   318  				types.Format_Default,
   319  				&IntervalEndpoint{types.Int(0), true},
   320  				&IntervalEndpoint{types.Int(20), true},
   321  			},
   322  			Interval{
   323  				types.Format_Default,
   324  				&IntervalEndpoint{types.Int(0), false},
   325  				&IntervalEndpoint{types.Int(20), false},
   326  			},
   327  			Interval{
   328  				types.Format_Default,
   329  				&IntervalEndpoint{types.Int(0), false},
   330  				&IntervalEndpoint{types.Int(20), false},
   331  			},
   332  			false,
   333  		},
   334  		{
   335  			"overlap with infinite interval",
   336  			Interval{
   337  				types.Format_Default,
   338  				&IntervalEndpoint{types.Int(10), true},
   339  				nil,
   340  			},
   341  			Interval{
   342  				types.Format_Default,
   343  				&IntervalEndpoint{types.Int(0), true},
   344  				&IntervalEndpoint{types.Int(20), true},
   345  			},
   346  			Interval{
   347  				types.Format_Default,
   348  				&IntervalEndpoint{types.Int(10), true},
   349  				&IntervalEndpoint{types.Int(20), true},
   350  			},
   351  			false,
   352  		},
   353  	}
   354  
   355  	for _, test := range tests {
   356  		t.Run(test.name, func(t *testing.T) {
   357  			res, err := intervalIntersection(test.in, test.in2)
   358  			assert.NoError(t, err)
   359  
   360  			assert.Equal(t, test.expected, res)
   361  		})
   362  	}
   363  }
   364  
   365  func TestIntervalCompositeSetIntersection(t *testing.T) {
   366  	tests := []struct {
   367  		name      string
   368  		in        Interval
   369  		cs        CompositeSet
   370  		expected  Set
   371  		expectErr bool
   372  	}{
   373  		{
   374  			"make universal set",
   375  			testInterv(&IntervalEndpoint{types.Int(0), true}, nil),
   376  			CompositeSet{
   377  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10), types.Int(20))),
   378  				[]Interval{
   379  					testInterv(nil, &IntervalEndpoint{types.Int(0), true}),
   380  				},
   381  			},
   382  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(10), types.Int(20))),
   383  			false,
   384  		},
   385  		{
   386  			"multiple intervals one overlapping",
   387  			testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   388  			CompositeSet{
   389  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10), types.Int(30))),
   390  				[]Interval{
   391  					testInterv(nil, &IntervalEndpoint{types.Int(0), true}),
   392  					testInterv(&IntervalEndpoint{types.Int(15), true}, &IntervalEndpoint{types.Int(25), true}),
   393  					testInterv(&IntervalEndpoint{types.Int(50), true}, &IntervalEndpoint{types.Int(100), true}),
   394  				},
   395  			},
   396  			CompositeSet{
   397  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(30))),
   398  				[]Interval{
   399  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(25), true}),
   400  				},
   401  			},
   402  			false,
   403  		},
   404  
   405  		{
   406  			"open interval intersection",
   407  			testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   408  			CompositeSet{
   409  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(25))),
   410  				[]Interval{
   411  					testInterv(&IntervalEndpoint{types.Int(0), true}, &IntervalEndpoint{types.Int(20), false}),
   412  					testInterv(&IntervalEndpoint{types.Int(30), false}, &IntervalEndpoint{types.Int(100), true}),
   413  				},
   414  			},
   415  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(25))),
   416  			false,
   417  		},
   418  
   419  		{
   420  			"single interval intersection result",
   421  			testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   422  			CompositeSet{
   423  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(35))),
   424  				[]Interval{
   425  					testInterv(&IntervalEndpoint{types.Int(0), true}, &IntervalEndpoint{types.Int(25), false}),
   426  					testInterv(&IntervalEndpoint{types.Int(30), false}, &IntervalEndpoint{types.Int(100), true}),
   427  				},
   428  			},
   429  			testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(25), false}),
   430  			false,
   431  		},
   432  
   433  		{
   434  			"empty intersection result",
   435  			testInterv(&IntervalEndpoint{types.Int(26), true}, &IntervalEndpoint{types.Int(29), true}),
   436  			CompositeSet{
   437  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(35))),
   438  				[]Interval{
   439  					testInterv(&IntervalEndpoint{types.Int(0), true}, &IntervalEndpoint{types.Int(25), false}),
   440  					testInterv(&IntervalEndpoint{types.Int(30), false}, &IntervalEndpoint{types.Int(100), true}),
   441  				},
   442  			},
   443  			EmptySet{},
   444  			false,
   445  		},
   446  	}
   447  
   448  	for _, test := range tests {
   449  		t.Run(test.name, func(t *testing.T) {
   450  			res, err := intervalCompositeSetIntersection(test.in, test.cs)
   451  			assertErr(t, test.expectErr, err)
   452  
   453  			assert.Equal(t, test.expected, res)
   454  		})
   455  	}
   456  }
   457  
   458  func TestCompositeSetIntersection(t *testing.T) {
   459  	tests := []struct {
   460  		name      string
   461  		cs1       CompositeSet
   462  		cs2       CompositeSet
   463  		expected  Set
   464  		expectErr bool
   465  	}{
   466  		{
   467  			"single point overlap with interval and finiteSet overlap",
   468  			CompositeSet{
   469  				FiniteSet{make(map[hash.Hash]types.Value)},
   470  				[]Interval{testInterv(&IntervalEndpoint{types.Int(0), true}, nil)},
   471  			},
   472  			CompositeSet{
   473  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10), types.Int(20))),
   474  				[]Interval{
   475  					testInterv(nil, &IntervalEndpoint{types.Int(0), true}),
   476  				},
   477  			},
   478  			mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(0), types.Int(10), types.Int(20))),
   479  			false,
   480  		},
   481  		{
   482  			"multiple intervals one overlapping",
   483  			CompositeSet{
   484  				FiniteSet{make(map[hash.Hash]types.Value)},
   485  				[]Interval{
   486  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   487  				},
   488  			},
   489  			CompositeSet{
   490  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10), types.Int(30))),
   491  				[]Interval{
   492  					testInterv(nil, &IntervalEndpoint{types.Int(0), true}),
   493  					testInterv(&IntervalEndpoint{types.Int(15), true}, &IntervalEndpoint{types.Int(25), true}),
   494  					testInterv(&IntervalEndpoint{types.Int(50), true}, &IntervalEndpoint{types.Int(100), true}),
   495  				},
   496  			},
   497  			CompositeSet{
   498  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(30))),
   499  				[]Interval{
   500  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(25), true}),
   501  				},
   502  			},
   503  			false,
   504  		},
   505  
   506  		{
   507  			"multiple intervals in multiple composite sets",
   508  			CompositeSet{
   509  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10), types.Int(15), types.Int(400))),
   510  				[]Interval{
   511  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   512  					testInterv(&IntervalEndpoint{types.Int(50), true}, &IntervalEndpoint{types.Int(100), true}),
   513  					testInterv(&IntervalEndpoint{types.Int(200), true}, &IntervalEndpoint{types.Int(300), true}),
   514  				},
   515  			},
   516  			CompositeSet{
   517  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(1), types.Int(10), types.Int(30))),
   518  				[]Interval{
   519  					testInterv(nil, &IntervalEndpoint{types.Int(0), true}),
   520  					testInterv(&IntervalEndpoint{types.Int(15), true}, &IntervalEndpoint{types.Int(25), true}),
   521  					testInterv(&IntervalEndpoint{types.Int(50), true}, &IntervalEndpoint{types.Int(100), true}),
   522  				},
   523  			},
   524  			CompositeSet{
   525  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(10), types.Int(15), types.Int(30))),
   526  				[]Interval{
   527  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(25), true}),
   528  					testInterv(&IntervalEndpoint{types.Int(50), true}, &IntervalEndpoint{types.Int(100), true}),
   529  				},
   530  			},
   531  			false,
   532  		},
   533  
   534  		{
   535  			"No overlap",
   536  			CompositeSet{
   537  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(-10))),
   538  				[]Interval{
   539  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   540  				},
   541  			},
   542  			CompositeSet{
   543  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(50))),
   544  				[]Interval{
   545  					testInterv(&IntervalEndpoint{types.Int(0), true}, &IntervalEndpoint{types.Int(10), false}),
   546  				},
   547  			},
   548  			EmptySet{},
   549  			false,
   550  		},
   551  
   552  		{
   553  			"Single interval result",
   554  			CompositeSet{
   555  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(-10))),
   556  				[]Interval{
   557  					testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(30), true}),
   558  				},
   559  			},
   560  			CompositeSet{
   561  				mustFiniteSet(NewFiniteSet(types.Format_Default, types.Int(50))),
   562  				[]Interval{
   563  					testInterv(&IntervalEndpoint{types.Int(0), true}, &IntervalEndpoint{types.Int(25), false}),
   564  				},
   565  			},
   566  			testInterv(&IntervalEndpoint{types.Int(20), true}, &IntervalEndpoint{types.Int(25), false}),
   567  			false,
   568  		},
   569  	}
   570  
   571  	for _, test := range tests {
   572  		t.Run(test.name, func(t *testing.T) {
   573  			res, err := compositeIntersection(test.cs1, test.cs2)
   574  			assertErr(t, test.expectErr, err)
   575  
   576  			assert.Equal(t, test.expected, res)
   577  		})
   578  	}
   579  
   580  }