github.com/dolthub/go-mysql-server@v0.18.0/enginetest/join_op_tests.go (about)

     1  // Copyright 2023 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 enginetest
    16  
    17  import (
    18  	"fmt"
    19  	"testing"
    20  
    21  	"github.com/stretchr/testify/require"
    22  
    23  	"github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup"
    24  	"github.com/dolthub/go-mysql-server/memory"
    25  	"github.com/dolthub/go-mysql-server/sql"
    26  	"github.com/dolthub/go-mysql-server/sql/memo"
    27  )
    28  
    29  type JoinOpTests struct {
    30  	Query    string
    31  	Expected []sql.Row
    32  	Skip     bool
    33  }
    34  
    35  var biasedCosters = map[string]memo.Coster{
    36  	"inner":     memo.NewInnerBiasedCoster(),
    37  	"lookup":    memo.NewLookupBiasedCoster(),
    38  	"hash":      memo.NewHashBiasedCoster(),
    39  	"merge":     memo.NewMergeBiasedCoster(),
    40  	"partial":   memo.NewPartialBiasedCoster(),
    41  	"rangeHeap": memo.NewRangeHeapBiasedCoster(),
    42  }
    43  
    44  func TestJoinOps(t *testing.T, harness Harness, tests []joinOpTest) {
    45  	for _, tt := range tests {
    46  		t.Run(tt.name, func(t *testing.T) {
    47  			e := mustNewEngine(t, harness)
    48  			defer e.Close()
    49  			for _, setup := range tt.setup {
    50  				for _, statement := range setup {
    51  					if sh, ok := harness.(SkippingHarness); ok {
    52  						if sh.SkipQueryTest(statement) {
    53  							t.Skip()
    54  						}
    55  					}
    56  					ctx := NewContext(harness)
    57  					RunQueryWithContext(t, e, harness, ctx, statement)
    58  				}
    59  			}
    60  
    61  			if pro, ok := e.EngineAnalyzer().Catalog.DbProvider.(*memory.DbProvider); ok {
    62  				newProv, err := pro.WithTableFunctions(memory.RequiredLookupTable{})
    63  				require.NoError(t, err)
    64  				e.EngineAnalyzer().Catalog.DbProvider = newProv.(sql.DatabaseProvider)
    65  			}
    66  
    67  			for k, c := range biasedCosters {
    68  				e.EngineAnalyzer().Coster = c
    69  				for _, tt := range tt.tests {
    70  					evalJoinCorrectness(t, harness, e, fmt.Sprintf("%s join: %s", k, tt.Query), tt.Query, tt.Expected, tt.Skip)
    71  				}
    72  			}
    73  		})
    74  	}
    75  }
    76  
    77  type joinOpTest struct {
    78  	name  string
    79  	setup [][]string
    80  	tests []JoinOpTests
    81  }
    82  
    83  var EngineOnlyJoinOpTests = []joinOpTest{
    84  	{
    85  		name: "required indexes avoid invalid plans",
    86  		setup: [][]string{
    87  			setup.MydbData[0],
    88  			{
    89  				"CREATE table xy (x int primary key, y int, unique index y_idx(y));",
    90  				"CREATE table uv (u int primary key, v int);",
    91  				"insert into xy values (1,0), (2,1), (0,2), (3,3);",
    92  				"insert into uv values (0,1), (1,1), (2,2), (3,2);",
    93  				`analyze table xy update histogram on x using data '{"row_count":1000}'`,
    94  				`analyze table uv update histogram on u using data '{"row_count":1000}'`,
    95  			},
    96  		},
    97  		tests: []JoinOpTests{
    98  			{
    99  				Query:    "select * from xy left join required_lookup_table('s', 2) on x = s",
   100  				Expected: []sql.Row{{0, 2, 0}, {1, 0, 1}, {2, 1, nil}, {3, 3, nil}},
   101  			},
   102  		},
   103  	},
   104  }
   105  
   106  var DefaultJoinOpTests = []joinOpTest{
   107  	{
   108  		name: "bug where transitive join edge drops filters",
   109  		setup: [][]string{
   110  			setup.MydbData[0],
   111  			{
   112  				"CREATE table xy (x int primary key, y int, unique index y_idx(y));",
   113  				"CREATE table uv (u int primary key, v int);",
   114  				"CREATE table ab (a int primary key, b int);",
   115  				"insert into xy values (1,0), (2,1), (0,2), (3,3);",
   116  				"insert into uv values (0,1), (1,1), (2,2), (3,2);",
   117  				"insert into ab values (0,2), (1,2), (2,2), (3,1);",
   118  				`analyze table xy update histogram on x using data '{"row_count":1000}'`,
   119  				`analyze table ab update histogram on a using data '{"row_count":1000}'`,
   120  				`analyze table uv update histogram on u using data '{"row_count":1000}'`,
   121  			},
   122  		},
   123  		tests: []JoinOpTests{
   124  			{
   125  				// This query is a small repro of a larger query caused by the intersection of several
   126  				// bugs. The query below should 1) move the filters out of the join condition, and then
   127  				// 2) push those hoisted filters on top of |uv|, where they are safe for join planning.
   128  				// At the time of this addition, filters in the middle of join trees are unsafe and
   129  				// at risk of being lost.
   130  				Query:    "select /*+ JOIN_ORDER(ab,xy,uv) */ * from xy join uv on (x = u and u in (0,2)) join ab on (x = a and v < 2)",
   131  				Expected: []sql.Row{{0, 2, 0, 1, 0, 2}},
   132  			},
   133  		},
   134  	},
   135  	{
   136  		name: "issue 5633, nil comparison in merge join",
   137  		setup: [][]string{
   138  			setup.MydbData[0],
   139  			{
   140  				"create table xyz (x int primary key, y int, z int, key(y), key(z))",
   141  				"create table uv (u int primary key, v int, unique key(u,v))",
   142  				"insert into xyz values (0,0,0),(1,1,1),(2,1,null),(3,2,null)",
   143  				"insert into uv values (0,0),(1,1),(2,null),(3,null)",
   144  			},
   145  		},
   146  		tests: []JoinOpTests{
   147  			{
   148  				Query:    "select x,u,z from xyz join uv on z = u where y = 1 order by 1,2",
   149  				Expected: []sql.Row{{1, 1, 1}},
   150  			},
   151  		},
   152  	},
   153  	{
   154  		name: "issue 5633 2, nil comparison in merge join",
   155  		setup: [][]string{
   156  			setup.MydbData[0],
   157  			{
   158  				"create table xyz (x int primary key, y int, z int, key(y), key(z))",
   159  				"create table uv (u int primary key, v int, unique key(u,v))",
   160  				"insert into xyz values (1,1,3),(2,1,2),(3,1,1)",
   161  				"insert into uv values (1,1),(2,2),(3,3)",
   162  			},
   163  		},
   164  		tests: []JoinOpTests{
   165  			{
   166  				Query:    "select x,u from xyz join uv on z = u where y = 1 order by 1,2",
   167  				Expected: []sql.Row{{1, 3}, {2, 2}, {3, 1}},
   168  			},
   169  		},
   170  	},
   171  	{
   172  		name: "left join tests",
   173  		setup: [][]string{
   174  			{
   175  				"create table xy (x int primary key, y int)",
   176  				"create table uv (u int primary key, v int, key(v))",
   177  				"insert into xy values (0,0),(2,2),(3,3),(4,4),(5,5),(7,7),(8,8),(10,10);",
   178  				"insert into uv values (0,0),(1,1),(3,3),(5,5),(6,5),(7,7),(9,9),(10,10);",
   179  			},
   180  		},
   181  		tests: []JoinOpTests{
   182  			{
   183  				Query:    "select x from xy left join uv on x = v",
   184  				Expected: []sql.Row{{0}, {2}, {3}, {4}, {5}, {5}, {7}, {8}, {10}},
   185  			},
   186  		},
   187  	},
   188  	{
   189  		name: "left join on array data",
   190  		setup: [][]string{
   191  			{
   192  				"create table xy (x binary(2) primary key, y binary(2))",
   193  				"create table uv (u binary(2) primary key, v binary(2))",
   194  				"insert into xy values (x'F0F0',x'1234'),(x'2345',x'3456');",
   195  				"insert into uv values (x'fedc',x'F0F0');",
   196  			},
   197  		},
   198  		tests: []JoinOpTests{
   199  			{
   200  				Query: "select HEX(x),HEX(u) from xy left join uv on x = v OR y = u",
   201  				Expected: []sql.Row{
   202  					{"2345", nil},
   203  					{"F0F0", "FEDC"},
   204  				},
   205  			},
   206  		},
   207  	},
   208  	{
   209  		name: "point lookups",
   210  		setup: [][]string{
   211  			setup.MydbData[0],
   212  			{
   213  				"create table uv (u int primary key, v int, unique key(v));",
   214  				"insert into uv values (1,1),(2,2);",
   215  				"create table xy (x int primary key, v int);",
   216  				"insert into xy values (0,0),(1,1);",
   217  			},
   218  		},
   219  		tests: []JoinOpTests{
   220  			{
   221  				Query:    "select * from xy where x not in (select v from uv)",
   222  				Expected: []sql.Row{{0, 0}},
   223  			},
   224  		},
   225  	},
   226  	{
   227  		name: "ordered distinct",
   228  		setup: [][]string{
   229  			setup.MydbData[0],
   230  			{
   231  				"create table uv (u int primary key, v int);",
   232  				"insert into uv values (1,1),(2,2),(3,1),(4,2);",
   233  				"create table xy (x int primary key, y int);",
   234  				"insert into xy values (1,1),(2,2);",
   235  			},
   236  		},
   237  		tests: []JoinOpTests{
   238  			{
   239  				Query:    `select /*+ JOIN_ORDER(scalarSubq0,xy) */ count(*) from xy where y in (select distinct v from uv);`,
   240  				Expected: []sql.Row{{2}},
   241  			},
   242  			{
   243  				Query:    `SELECT /*+ JOIN_ORDER(scalarSubq0,xy) */ count(*) from xy where y in (select distinct u from uv);`,
   244  				Expected: []sql.Row{{2}},
   245  			},
   246  		},
   247  	},
   248  	{
   249  		name: "union/intersect/except joins",
   250  		setup: [][]string{
   251  			setup.MydbData[0],
   252  			{
   253  				"create table uv (u int primary key, v int);",
   254  				"insert into uv values (1,1),(2,2),(3,1),(4,2);",
   255  				"create table xy (x int primary key, y int);",
   256  				"insert into xy values (1,1),(2,2);",
   257  			},
   258  		},
   259  		tests: []JoinOpTests{
   260  			{
   261  				Query:    "select * from xy where x = 1 and exists (select 1 union select 1)",
   262  				Expected: []sql.Row{{1, 1}},
   263  			},
   264  			{
   265  				Query:    "select * from xy where x = 1 and x in (select y from xy union select 1)",
   266  				Expected: []sql.Row{{1, 1}},
   267  			},
   268  			{
   269  				Query:    "select * from xy where x = 1 and x in (select y from xy intersect select 1)",
   270  				Expected: []sql.Row{{1, 1}},
   271  			},
   272  			{
   273  				Query:    "select * from xy where x = 1 and x in (select y from xy except select 2)",
   274  				Expected: []sql.Row{{1, 1}},
   275  			},
   276  			{
   277  				Query: "select * from xy where x = 1 intersect select * from uv;",
   278  				Expected: []sql.Row{
   279  					{1, 1},
   280  				},
   281  			},
   282  			{
   283  				Query: "select * from uv where u < 4 except select * from xy;",
   284  				Expected: []sql.Row{
   285  					{3, 1},
   286  				},
   287  			},
   288  			{
   289  				Query: "select * from xy, uv where x = u intersect select * from xy, uv where x = u order by x, y, u, v;",
   290  				Expected: []sql.Row{
   291  					{1, 1, 1, 1},
   292  					{2, 2, 2, 2},
   293  				},
   294  			},
   295  			{
   296  				Query: "select * from xy, uv where x != u except select * from xy, uv where y != v order by x, y, u, v;",
   297  				Expected: []sql.Row{
   298  					{1, 1, 3, 1},
   299  					{2, 2, 4, 2},
   300  				},
   301  			},
   302  			{
   303  				Query: "select * from (select * from uv where u < 4 except select * from xy) a, (select * from xy intersect select * from uv) b order by u, v, x, y;",
   304  				Expected: []sql.Row{
   305  					{3, 1, 1, 1},
   306  					{3, 1, 2, 2},
   307  				},
   308  			},
   309  		},
   310  	},
   311  	{
   312  		name: "4-way join tests",
   313  		setup: [][]string{
   314  			setup.MydbData[0],
   315  			setup.MytableData[0],
   316  			setup.OthertableData[0],
   317  			setup.Pk_tablesData[0],
   318  			setup.NiltableData[0],
   319  			setup.TabletestData[0],
   320  			setup.XyData[0],
   321  		},
   322  		tests: []JoinOpTests{
   323  			{
   324  				Query:    `SELECT * from xy join uv on x = u and y = NOW()`,
   325  				Expected: []sql.Row{},
   326  			},
   327  			{
   328  				Query: `SELECT xy.x, xy.y
   329  					FROM xy
   330  					WHERE EXISTS (
   331  					SELECT 1 FROM uv WHERE xy.x = uv.v AND (EXISTS (
   332  					SELECT 1 FROM ab WHERE uv.u = ab.b)))`,
   333  				Expected: []sql.Row{{1, 0}, {2, 1}},
   334  			},
   335  			{
   336  				// natural join w/ inner join
   337  				Query: "select * from mytable t1 natural join mytable t2 join othertable t3 on t2.i = t3.i2;",
   338  				Expected: []sql.Row{
   339  					{1, "first row", "third", 1},
   340  					{2, "second row", "second", 2},
   341  					{3, "third row", "first", 3},
   342  				},
   343  			},
   344  			{
   345  				Query: `
   346  SELECT SUM(x) FROM xy WHERE x IN (
   347    SELECT u FROM uv WHERE u IN (
   348      SELECT a FROM ab WHERE a = 2
   349      )
   350    ) AND
   351    x = 2;`,
   352  				Expected: []sql.Row{{float64(2)}},
   353  			},
   354  			{
   355  				Query:    "select * from ab left join uv on a = u where exists (select * from uv where false)",
   356  				Expected: []sql.Row{},
   357  			},
   358  			{
   359  				Query: "select * from ab left join (select * from uv where false) s on a = u order by 1;",
   360  				Expected: []sql.Row{
   361  					{0, 2, nil, nil},
   362  					{1, 2, nil, nil},
   363  					{2, 2, nil, nil},
   364  					{3, 1, nil, nil},
   365  				},
   366  			},
   367  			{
   368  				Query:    "select * from ab right join (select * from uv where false) s on a = u order by 1;",
   369  				Expected: []sql.Row{},
   370  			},
   371  			{
   372  				Query: "select * from mytable where exists (select * from mytable where i = 1) order by 1;",
   373  				Expected: []sql.Row{
   374  					{1, "first row"},
   375  					{2, "second row"},
   376  					{3, "third row"},
   377  				},
   378  			},
   379  			// queries that test subquery hoisting
   380  			{
   381  				// case 1: condition uses columns from both sides
   382  				Query: "/*+case1*/ select * from ab where exists (select * from xy where ab.a = xy.x + 3)",
   383  				Expected: []sql.Row{
   384  					{3, 1},
   385  				},
   386  			},
   387  			{
   388  				// case 1N: NOT EXISTS condition uses columns from both sides
   389  				Query: "/*+case1N*/ select * from ab where not exists (select * from xy where ab.a = xy.x + 3)",
   390  				Expected: []sql.Row{
   391  					{0, 2},
   392  					{1, 2},
   393  					{2, 2},
   394  				},
   395  			},
   396  			{
   397  				// case 2: condition uses columns from left side only
   398  				Query:    "/*+case2*/ select * from ab where exists (select * from xy where a = 1)",
   399  				Expected: []sql.Row{{1, 2}},
   400  			},
   401  			{
   402  				// case 2N: NOT EXISTS condition uses columns from left side only
   403  				Query: "/*+case2N*/ select * from ab where not exists (select * from xy where a = 1)",
   404  				Expected: []sql.Row{
   405  					{0, 2},
   406  					{2, 2},
   407  					{3, 1},
   408  				},
   409  			},
   410  			{
   411  				// case 3: condition uses columns from right side only
   412  				Query: "/*+case3*/ select * from ab where exists (select * from xy where 1 = xy.x)",
   413  				Expected: []sql.Row{
   414  					{0, 2},
   415  					{1, 2},
   416  					{2, 2},
   417  					{3, 1},
   418  				},
   419  			},
   420  			{
   421  				// case 3N: NOT EXISTS condition uses columns from right side only
   422  				Query: "/*+case3N*/ select * from ab where not exists (select * from xy where 10 = xy.x)",
   423  				Expected: []sql.Row{
   424  					{0, 2},
   425  					{1, 2},
   426  					{2, 2},
   427  					{3, 1},
   428  				},
   429  			},
   430  			{
   431  				// case 4a: condition uses no columns from either side, and condition is true
   432  				Query: "/*+case4a*/ select * from ab where exists (select * from xy where 1 = 1)",
   433  				Expected: []sql.Row{
   434  					{0, 2},
   435  					{1, 2},
   436  					{2, 2},
   437  					{3, 1},
   438  				},
   439  			},
   440  			{
   441  				// case 4aN: NOT EXISTS condition uses no columns from either side, and condition is true
   442  				Query:    "/*+case4aN*/ select * from ab where not exists (select * from xy where 1 = 1)",
   443  				Expected: []sql.Row{},
   444  			},
   445  			{
   446  				// case 4b: condition uses no columns from either side, and condition is false
   447  				Query:    "/*+case4b*/ select * from ab where exists (select * from xy where 1 = 0)",
   448  				Expected: []sql.Row{},
   449  			},
   450  			{
   451  				// case 4bN: NOT EXISTS condition uses no columns from either side, and condition is false
   452  				Query:    "/*+case4bN*/ select * from ab where not exists (select * from xy where 1 = 0)",
   453  				Expected: []sql.Row{{0, 2}, {1, 2}, {2, 2}, {3, 1}},
   454  			},
   455  			{
   456  				// test more complex scopes
   457  				Query: "select x, 1 in (select a from ab where exists (select * from uv where a = u)) s from xy",
   458  				Expected: []sql.Row{
   459  					{0, true},
   460  					{1, true},
   461  					{2, true},
   462  					{3, true},
   463  				},
   464  			},
   465  			{
   466  				Query:    `select a.i,a.f, b.i2 from niltable a left join niltable b on a.i = b.i2`,
   467  				Expected: []sql.Row{{1, nil, nil}, {2, nil, 2}, {3, nil, nil}, {4, 4.0, 4}, {5, 5.0, nil}, {6, 6.0, 6}},
   468  			},
   469  			{
   470  				Query: `SELECT i, s, i2, s2 FROM MYTABLE JOIN OTHERTABLE ON i = i2 AND NOT (s2 <=> s)`,
   471  				Expected: []sql.Row{
   472  					{1, "first row", 1, "third"},
   473  					{2, "second row", 2, "second"},
   474  					{3, "third row", 3, "first"},
   475  				},
   476  			},
   477  			{
   478  				Query: `SELECT i, s, i2, s2 FROM MYTABLE JOIN OTHERTABLE ON i = i2 AND NOT (s2 = s)`,
   479  				Expected: []sql.Row{
   480  					{1, "first row", 1, "third"},
   481  					{2, "second row", 2, "second"},
   482  					{3, "third row", 3, "first"},
   483  				},
   484  			},
   485  			{
   486  				Query: `SELECT i, s, i2, s2 FROM MYTABLE JOIN OTHERTABLE ON i = i2 AND CONCAT(s, s2) IS NOT NULL`,
   487  				Expected: []sql.Row{
   488  					{1, "first row", 1, "third"},
   489  					{2, "second row", 2, "second"},
   490  					{3, "third row", 3, "first"},
   491  				},
   492  			},
   493  			{
   494  				Query: `SELECT * FROM mytable mt JOIN othertable ot ON ot.i2 = (SELECT i2 FROM othertable WHERE s2 = "second") AND mt.i = ot.i2 JOIN mytable mt2 ON mt.i = mt2.i`,
   495  				Expected: []sql.Row{
   496  					{2, "second row", "second", 2, 2, "second row"},
   497  				},
   498  			},
   499  			{
   500  				Query:    "SELECT l.i, r.i2 FROM niltable l INNER JOIN niltable r ON l.i2 = r.i2 ORDER BY 1",
   501  				Expected: []sql.Row{{2, 2}, {4, 4}, {6, 6}},
   502  			},
   503  			{
   504  				Query:    "SELECT l.i, r.i2 FROM niltable l INNER JOIN niltable r ON l.i2 != r.i2 ORDER BY 1, 2",
   505  				Expected: []sql.Row{{2, 4}, {2, 6}, {4, 2}, {4, 6}, {6, 2}, {6, 4}},
   506  			},
   507  			{
   508  				Query:    "SELECT l.i, r.i2 FROM niltable l INNER JOIN niltable r ON l.i2 <=> r.i2 ORDER BY 1 ASC",
   509  				Expected: []sql.Row{{1, nil}, {1, nil}, {1, nil}, {2, 2}, {3, nil}, {3, nil}, {3, nil}, {4, 4}, {5, nil}, {5, nil}, {5, nil}, {6, 6}},
   510  			},
   511  			{
   512  				// TODO: ORDER BY should apply to the union. The parser is wrong.
   513  				Query: `SELECT s2, i2, i
   514  			FROM (SELECT * FROM mytable) mytable
   515  			RIGHT JOIN
   516  				((SELECT i2, s2 FROM othertable ORDER BY i2 ASC)
   517  				 UNION ALL
   518  				 SELECT CAST(4 AS SIGNED) AS i2, "not found" AS s2 FROM DUAL) othertable
   519  			ON i2 = i`,
   520  				Expected: []sql.Row{
   521  					{"third", 1, 1},
   522  					{"second", 2, 2},
   523  					{"first", 3, 3},
   524  					{"not found", 4, nil},
   525  				},
   526  			},
   527  			// re: https://github.com/dolthub/go-mysql-server/pull/2292
   528  			{
   529  				Query: `SELECT
   530  			"testing" AS s,
   531  			(SELECT max(i)
   532  			FROM (SELECT * FROM mytable) mytable
   533  			RIGHT JOIN
   534  				((SELECT i2, s2 FROM othertable ORDER BY i2 ASC)
   535  				 UNION ALL
   536  				 SELECT CAST(4 AS SIGNED) AS i2, "not found" AS s2 FROM DUAL) othertable
   537  				ON i2 = i) AS rj
   538  			FROM DUAL`,
   539  				Expected: []sql.Row{
   540  					{"testing", 3},
   541  				},
   542  				Skip: true,
   543  			},
   544  			{
   545  				Query: `SELECT
   546  			"testing" AS s,
   547  			(SELECT max(i2)
   548  			FROM (SELECT * FROM mytable) mytable
   549  			RIGHT JOIN
   550  				((SELECT i2, s2 FROM othertable ORDER BY i2 ASC)
   551  				 UNION ALL
   552  				 SELECT CAST(4 AS SIGNED) AS i2, "not found" AS s2 FROM DUAL) othertable
   553  				ON i2 = i) AS rj
   554  			FROM DUAL`,
   555  				Expected: []sql.Row{
   556  					{"testing", 4},
   557  				},
   558  				Skip: true,
   559  			},
   560  			{
   561  				Query: "SELECT substring(mytable.s, 1, 5) AS s FROM mytable INNER JOIN othertable ON (substring(mytable.s, 1, 5) = SUBSTRING(othertable.s2, 1, 5)) GROUP BY 1",
   562  				Expected: []sql.Row{
   563  					{"third"},
   564  					{"secon"},
   565  					{"first"},
   566  				},
   567  			},
   568  			{
   569  				Query: "SELECT t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   570  				Expected: []sql.Row{
   571  					{2},
   572  				},
   573  			},
   574  			{
   575  				Query: "SELECT /*+ JOIN_ORDER(t1,t2) */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   576  				Expected: []sql.Row{
   577  					{2},
   578  				},
   579  			},
   580  			{
   581  				Query: "SELECT /*+ JOIN_ORDER(t2,t1) */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   582  				Expected: []sql.Row{
   583  					{2},
   584  				},
   585  			},
   586  			{
   587  				Query: "SELECT /*+ JOIN_ORDER(t1) */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   588  				Expected: []sql.Row{
   589  					{2},
   590  				},
   591  			},
   592  			{
   593  				Query: "SELECT /*+ JOIN_ORDER(t1, mytable) */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   594  				Expected: []sql.Row{
   595  					{2},
   596  				},
   597  			},
   598  			{
   599  				Query: "SELECT /*+ JOIN_ORDER(t1, not_exist) */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   600  				Expected: []sql.Row{
   601  					{2},
   602  				},
   603  			},
   604  			{
   605  				Query: "SELECT /*+ NOTHING(abc) */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   606  				Expected: []sql.Row{
   607  					{2},
   608  				},
   609  			},
   610  			{
   611  				Query: "SELECT /*+ JOIN_ORDER( */ t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 1",
   612  				Expected: []sql.Row{
   613  					{2},
   614  				},
   615  			},
   616  			{
   617  				Query: "select mytable.i as i2, othertable.i2 as i from mytable join othertable on i = i2 order by 1",
   618  				Expected: []sql.Row{
   619  					{1, 1},
   620  					{2, 2},
   621  					{3, 3},
   622  				},
   623  			},
   624  			{
   625  				Query: "SELECT i, s, i2, s2 FROM mytable INNER JOIN othertable ON i = i2 OR s = s2 order by 1",
   626  				Expected: []sql.Row{
   627  					{1, "first row", 1, "third"},
   628  					{2, "second row", 2, "second"},
   629  					{3, "third row", 3, "first"},
   630  				},
   631  			},
   632  			{
   633  				Query: "SELECT i, s, i2, s2 FROM mytable INNER JOIN othertable ON i = i2 OR SUBSTRING_INDEX(s, ' ', 1) = s2 order by 1, 3",
   634  				Expected: []sql.Row{
   635  					{1, "first row", 1, "third"},
   636  					{1, "first row", 3, "first"},
   637  					{2, "second row", 2, "second"},
   638  					{3, "third row", 1, "third"},
   639  					{3, "third row", 3, "first"},
   640  				},
   641  			},
   642  			{
   643  				Query: "SELECT i, s, i2, s2 FROM mytable INNER JOIN othertable ON i = i2 OR SUBSTRING_INDEX(s, ' ', 1) = s2 OR SUBSTRING_INDEX(s, ' ', 2) = s2 order by 1, 3",
   644  				Expected: []sql.Row{
   645  					{1, "first row", 1, "third"},
   646  					{1, "first row", 3, "first"},
   647  					{2, "second row", 2, "second"},
   648  					{3, "third row", 1, "third"},
   649  					{3, "third row", 3, "first"},
   650  				},
   651  			},
   652  			{
   653  				Query: "SELECT i, s, i2, s2 FROM mytable INNER JOIN othertable ON i = i2 OR SUBSTRING_INDEX(s, ' ', 2) = s2 OR SUBSTRING_INDEX(s, ' ', 1) = s2 order by 1, 3",
   654  				Expected: []sql.Row{
   655  					{1, "first row", 1, "third"},
   656  					{1, "first row", 3, "first"},
   657  					{2, "second row", 2, "second"},
   658  					{3, "third row", 1, "third"},
   659  					{3, "third row", 3, "first"},
   660  				},
   661  			},
   662  			{
   663  				Query: "SELECT i, s, i2, s2 FROM mytable INNER JOIN othertable ON SUBSTRING_INDEX(s, ' ', 2) = s2 OR SUBSTRING_INDEX(s, ' ', 1) = s2 OR i = i2 order by 1, 3",
   664  				Expected: []sql.Row{
   665  					{1, "first row", 1, "third"},
   666  					{1, "first row", 3, "first"},
   667  					{2, "second row", 2, "second"},
   668  					{3, "third row", 1, "third"},
   669  					{3, "third row", 3, "first"},
   670  				},
   671  			},
   672  			{
   673  				Query:    "SELECT t1.i FROM mytable t1 JOIN mytable t2 on t1.i = t2.i + 1 where t1.i = 2 and t2.i = 3",
   674  				Expected: []sql.Row{},
   675  			},
   676  			{
   677  				Query: "SELECT i, i2, s2 FROM mytable INNER JOIN othertable ON i = i2 ORDER BY i",
   678  				Expected: []sql.Row{
   679  					{int64(1), int64(1), "third"},
   680  					{int64(2), int64(2), "second"},
   681  					{int64(3), int64(3), "first"},
   682  				},
   683  			},
   684  			{
   685  				Query: "SELECT i, i2, s2 FROM mytable as OTHERTABLE INNER JOIN othertable as MYTABLE ON i = i2 ORDER BY i",
   686  				Expected: []sql.Row{
   687  					{int64(1), int64(1), "third"},
   688  					{int64(2), int64(2), "second"},
   689  					{int64(3), int64(3), "first"},
   690  				},
   691  			},
   692  			{
   693  				Query: "SELECT s2, i2, i FROM mytable INNER JOIN othertable ON i = i2 ORDER BY i",
   694  				Expected: []sql.Row{
   695  					{"third", int64(1), int64(1)},
   696  					{"second", int64(2), int64(2)},
   697  					{"first", int64(3), int64(3)},
   698  				},
   699  			},
   700  			{
   701  				Query: "SELECT i, i2, s2 FROM othertable JOIN mytable  ON i = i2 ORDER BY i",
   702  				Expected: []sql.Row{
   703  					{int64(1), int64(1), "third"},
   704  					{int64(2), int64(2), "second"},
   705  					{int64(3), int64(3), "first"},
   706  				},
   707  			},
   708  			{
   709  				Query: "SELECT s2, i2, i FROM othertable JOIN mytable ON i = i2 ORDER BY i",
   710  				Expected: []sql.Row{
   711  					{"third", int64(1), int64(1)},
   712  					{"second", int64(2), int64(2)},
   713  					{"first", int64(3), int64(3)},
   714  				},
   715  			},
   716  			{
   717  				Query: "SELECT s FROM mytable INNER JOIN othertable " +
   718  					"ON substring(s2, 1, 2) != '' AND i = i2 ORDER BY 1",
   719  				Expected: []sql.Row{
   720  					{"first row"},
   721  					{"second row"},
   722  					{"third row"},
   723  				},
   724  			},
   725  			{
   726  				Query: `SELECT i FROM mytable NATURAL JOIN tabletest`,
   727  				Expected: []sql.Row{
   728  					{int64(1)},
   729  					{int64(2)},
   730  					{int64(3)},
   731  				},
   732  			},
   733  			{
   734  				Query: `SELECT i FROM mytable AS t NATURAL JOIN tabletest AS test`,
   735  				Expected: []sql.Row{
   736  					{int64(1)},
   737  					{int64(2)},
   738  					{int64(3)},
   739  				},
   740  			},
   741  			{
   742  				Query: `SELECT t.i, test.s FROM mytable AS t NATURAL JOIN tabletest AS test`,
   743  				Expected: []sql.Row{
   744  					{int64(1), "first row"},
   745  					{int64(2), "second row"},
   746  					{int64(3), "third row"},
   747  				},
   748  			},
   749  			{
   750  				Query: `SELECT * FROM tabletest, mytable mt INNER JOIN othertable ot ON mt.i = ot.i2`,
   751  				Expected: []sql.Row{
   752  					{int64(1), "first row", int64(1), "first row", "third", int64(1)},
   753  					{int64(1), "first row", int64(2), "second row", "second", int64(2)},
   754  					{int64(1), "first row", int64(3), "third row", "first", int64(3)},
   755  					{int64(2), "second row", int64(1), "first row", "third", int64(1)},
   756  					{int64(2), "second row", int64(2), "second row", "second", int64(2)},
   757  					{int64(2), "second row", int64(3), "third row", "first", int64(3)},
   758  					{int64(3), "third row", int64(1), "first row", "third", int64(1)},
   759  					{int64(3), "third row", int64(2), "second row", "second", int64(2)},
   760  					{int64(3), "third row", int64(3), "third row", "first", int64(3)},
   761  				},
   762  			},
   763  			{
   764  				Query: `SELECT * FROM tabletest join mytable mt INNER JOIN othertable ot ON tabletest.i = ot.i2 order by 1,3,6`,
   765  				Expected: []sql.Row{
   766  					{int64(1), "first row", int64(1), "first row", "third", int64(1)},
   767  					{int64(1), "first row", int64(2), "second row", "third", int64(1)},
   768  					{int64(1), "first row", int64(3), "third row", "third", int64(1)},
   769  					{int64(2), "second row", int64(1), "first row", "second", int64(2)},
   770  					{int64(2), "second row", int64(2), "second row", "second", int64(2)},
   771  					{int64(2), "second row", int64(3), "third row", "second", int64(2)},
   772  					{int64(3), "third row", int64(1), "first row", "first", int64(3)},
   773  					{int64(3), "third row", int64(2), "second row", "first", int64(3)},
   774  					{int64(3), "third row", int64(3), "third row", "first", int64(3)},
   775  				},
   776  			},
   777  			{
   778  				Query: `SELECT * FROM mytable mt INNER JOIN othertable ot ON mt.i = ot.i2 AND mt.i > 2`,
   779  				Expected: []sql.Row{
   780  					{int64(3), "third row", "first", int64(3)},
   781  				},
   782  			},
   783  			{
   784  				Query: `SELECT * FROM othertable ot INNER JOIN mytable mt ON mt.i = ot.i2 AND mt.i > 2`,
   785  				Expected: []sql.Row{
   786  					{"first", int64(3), int64(3), "third row"},
   787  				},
   788  			},
   789  			{
   790  				Query: "SELECT i, i2, s2 FROM mytable LEFT JOIN othertable ON i = i2 - 1",
   791  				Expected: []sql.Row{
   792  					{int64(1), int64(2), "second"},
   793  					{int64(2), int64(3), "first"},
   794  					{int64(3), nil, nil},
   795  				},
   796  			},
   797  			{
   798  				Query: "SELECT i, i2, s2 FROM mytable RIGHT JOIN othertable ON i = i2 - 1",
   799  				Expected: []sql.Row{
   800  					{nil, int64(1), "third"},
   801  					{int64(1), int64(2), "second"},
   802  					{int64(2), int64(3), "first"},
   803  				},
   804  			},
   805  			{
   806  				Query: "SELECT i, i2, s2 FROM mytable LEFT OUTER JOIN othertable ON i = i2 - 1",
   807  				Expected: []sql.Row{
   808  					{int64(1), int64(2), "second"},
   809  					{int64(2), int64(3), "first"},
   810  					{int64(3), nil, nil},
   811  				},
   812  			},
   813  			{
   814  				Query: "SELECT i, i2, s2 FROM mytable RIGHT OUTER JOIN othertable ON i = i2 - 1",
   815  				Expected: []sql.Row{
   816  					{nil, int64(1), "third"},
   817  					{int64(1), int64(2), "second"},
   818  					{int64(2), int64(3), "first"},
   819  				},
   820  			},
   821  			{
   822  				Query: `SELECT sub.i, sub.i2, sub.s2, ot.i2, ot.s2
   823  				FROM othertable ot INNER JOIN
   824  					(SELECT i, i2, s2 FROM mytable INNER JOIN othertable ON i = i2) sub
   825  				ON sub.i = ot.i2 order by 1`,
   826  				Expected: []sql.Row{
   827  					{1, 1, "third", 1, "third"},
   828  					{2, 2, "second", 2, "second"},
   829  					{3, 3, "first", 3, "first"},
   830  				},
   831  			},
   832  			{
   833  				Query: `SELECT sub.i, sub.i2, sub.s2, ot.i2, ot.s2
   834  				FROM (SELECT i, i2, s2 FROM mytable INNER JOIN othertable ON i = i2) sub
   835  				INNER JOIN othertable ot
   836  				ON sub.i = ot.i2 order by 1`,
   837  				Expected: []sql.Row{
   838  					{1, 1, "third", 1, "third"},
   839  					{2, 2, "second", 2, "second"},
   840  					{3, 3, "first", 3, "first"},
   841  				},
   842  			},
   843  			{
   844  				Query: "SELECT one_pk.c5,pk1,pk2 FROM one_pk JOIN two_pk ON pk=pk1 ORDER BY 1,2,3",
   845  				Expected: []sql.Row{
   846  					{4, 0, 0},
   847  					{4, 0, 1},
   848  					{14, 1, 0},
   849  					{14, 1, 1},
   850  				},
   851  			},
   852  			{
   853  				Query: "SELECT opk.c5,pk1,pk2 FROM one_pk opk JOIN two_pk tpk ON pk=pk1 ORDER BY 1,2,3",
   854  				Expected: []sql.Row{
   855  					{4, 0, 0},
   856  					{4, 0, 1},
   857  					{14, 1, 0},
   858  					{14, 1, 1},
   859  				},
   860  			},
   861  			{
   862  				Query: "SELECT opk.c5,pk1,pk2 FROM one_pk opk JOIN two_pk tpk ON opk.pk=tpk.pk1 ORDER BY 1,2,3",
   863  				Expected: []sql.Row{
   864  					{4, 0, 0},
   865  					{4, 0, 1},
   866  					{14, 1, 0},
   867  					{14, 1, 1},
   868  				},
   869  			},
   870  			{
   871  				Query: "SELECT pk,pk1,pk2 FROM one_pk JOIN two_pk ON one_pk.c1=two_pk.c1 WHERE pk=1 ORDER BY 1,2,3",
   872  				Expected: []sql.Row{
   873  					{1, 0, 1},
   874  				},
   875  			},
   876  			{
   877  				Query: "SELECT pk,pk1,pk2 FROM one_pk JOIN two_pk ON one_pk.pk=two_pk.pk1 AND one_pk.pk=two_pk.pk2 ORDER BY 1,2,3",
   878  				Expected: []sql.Row{
   879  					{0, 0, 0},
   880  					{1, 1, 1},
   881  				},
   882  			},
   883  			{
   884  				Query: "SELECT pk,pk1,pk2 FROM one_pk opk JOIN two_pk tpk ON opk.pk=tpk.pk1 AND opk.pk=tpk.pk2 ORDER BY 1,2,3",
   885  				Expected: []sql.Row{
   886  					{0, 0, 0},
   887  					{1, 1, 1},
   888  				},
   889  			},
   890  			{
   891  				Query: "SELECT pk,pk1,pk2 FROM one_pk opk JOIN two_pk tpk ON pk=tpk.pk1 AND pk=tpk.pk2 ORDER BY 1,2,3",
   892  				Expected: []sql.Row{
   893  					{0, 0, 0},
   894  					{1, 1, 1},
   895  				},
   896  			},
   897  			{
   898  				Query: `SELECT pk,tpk.pk1,tpk2.pk1,tpk.pk2,tpk2.pk2 FROM one_pk
   899  						LEFT JOIN two_pk tpk ON one_pk.pk=tpk.pk1 AND one_pk.pk-1=tpk.pk2
   900  						LEFT JOIN two_pk tpk2 ON tpk2.pk1=TPK.pk2 AND TPK2.pk2=tpk.pk1
   901  						ORDER BY 1`,
   902  				Expected: []sql.Row{
   903  					{0, nil, nil, nil, nil},
   904  					{1, 1, 0, 0, 1},
   905  					{2, nil, nil, nil, nil},
   906  					{3, nil, nil, nil, nil},
   907  				},
   908  			},
   909  			{
   910  				Query: `SELECT pk,tpk.pk1,tpk2.pk1,tpk.pk2,tpk2.pk2 FROM one_pk
   911  						JOIN two_pk tpk ON pk=tpk.pk1 AND pk-1=tpk.pk2
   912  						JOIN two_pk tpk2 ON pk-1=TPK2.pk1 AND pk=tpk2.pk2
   913  						ORDER BY 1`,
   914  				Expected: []sql.Row{
   915  					{1, 1, 0, 0, 1},
   916  				},
   917  			},
   918  			{
   919  				Query: `SELECT pk,tpk.pk1,tpk2.pk1,tpk.pk2,tpk2.pk2 FROM one_pk
   920  						JOIN two_pk tpk ON pk=tpk.pk1 AND pk-1=tpk.pk2
   921  						JOIN two_pk tpk2 ON pk-1=TPK2.pk1 AND pk=tpk2.pk2
   922  						ORDER BY 1`,
   923  				Expected: []sql.Row{
   924  					{1, 1, 0, 0, 1},
   925  				},
   926  			},
   927  			{
   928  				Query: "SELECT pk,pk1,pk2 FROM one_pk LEFT JOIN two_pk ON one_pk.pk=two_pk.pk1 AND one_pk.pk=two_pk.pk2 ORDER BY 1,2,3",
   929  				Expected: []sql.Row{
   930  					{0, 0, 0},
   931  					{1, 1, 1},
   932  					{2, nil, nil},
   933  					{3, nil, nil},
   934  				},
   935  			},
   936  			{
   937  				Query: "SELECT pk,pk1,pk2 FROM one_pk RIGHT JOIN two_pk ON one_pk.pk=two_pk.pk1 AND one_pk.pk=two_pk.pk2 ORDER BY 1,2,3",
   938  				Expected: []sql.Row{
   939  					{nil, 0, 1},
   940  					{nil, 1, 0},
   941  					{0, 0, 0},
   942  					{1, 1, 1},
   943  				},
   944  			},
   945  			{
   946  				Query: "SELECT i,pk1,pk2 FROM mytable JOIN two_pk ON i-1=pk1 AND i-2=pk2 ORDER BY 1,2,3",
   947  				Expected: []sql.Row{
   948  					{int64(2), 1, 0},
   949  				},
   950  			},
   951  			{
   952  				Query: "SELECT a.pk1,a.pk2,b.pk1,b.pk2 FROM two_pk a JOIN two_pk b ON a.pk1=b.pk2 AND a.pk2=b.pk1 ORDER BY 1,2,3",
   953  				Expected: []sql.Row{
   954  					{0, 0, 0, 0},
   955  					{0, 1, 1, 0},
   956  					{1, 0, 0, 1},
   957  					{1, 1, 1, 1},
   958  				},
   959  			},
   960  			{
   961  				Query: "SELECT a.pk1,a.pk2,b.pk1,b.pk2 FROM two_pk a JOIN two_pk b ON a.pk1=b.pk1 AND a.pk2=b.pk2 ORDER BY 1,2,3",
   962  				Expected: []sql.Row{
   963  					{0, 0, 0, 0},
   964  					{0, 1, 0, 1},
   965  					{1, 0, 1, 0},
   966  					{1, 1, 1, 1},
   967  				},
   968  			},
   969  			{
   970  				Query: "SELECT a.pk1,a.pk2,b.pk1,b.pk2 FROM two_pk a, two_pk b WHERE a.pk1=b.pk1 AND a.pk2=b.pk2 ORDER BY 1,2,3",
   971  				Expected: []sql.Row{
   972  					{0, 0, 0, 0},
   973  					{0, 1, 0, 1},
   974  					{1, 0, 1, 0},
   975  					{1, 1, 1, 1},
   976  				},
   977  			},
   978  			{
   979  				Query: "SELECT a.pk1,a.pk2,b.pk1,b.pk2 FROM two_pk a JOIN two_pk b ON b.pk1=a.pk1 AND a.pk2=b.pk2 ORDER BY 1,2,3",
   980  				Expected: []sql.Row{
   981  					{0, 0, 0, 0},
   982  					{0, 1, 0, 1},
   983  					{1, 0, 1, 0},
   984  					{1, 1, 1, 1},
   985  				},
   986  			},
   987  			{
   988  				Query: "SELECT a.pk1,a.pk2,b.pk1,b.pk2 FROM two_pk a JOIN two_pk b ON a.pk1+1=b.pk1 AND a.pk2+1=b.pk2 ORDER BY 1,2,3",
   989  				Expected: []sql.Row{
   990  					{0, 0, 1, 1},
   991  				},
   992  			},
   993  			{
   994  				Query: "SELECT pk,pk1,pk2 FROM one_pk LEFT JOIN two_pk ON pk=pk1 ORDER BY 1,2,3",
   995  				Expected: []sql.Row{
   996  					{0, 0, 0},
   997  					{0, 0, 1},
   998  					{1, 1, 0},
   999  					{1, 1, 1},
  1000  					{2, nil, nil},
  1001  					{3, nil, nil},
  1002  				},
  1003  			},
  1004  			{
  1005  				Query: "SELECT pk,i2,f FROM one_pk LEFT JOIN niltable ON pk=i2 ORDER BY 1",
  1006  				Expected: []sql.Row{
  1007  					{0, nil, nil},
  1008  					{1, nil, nil},
  1009  					{2, int64(2), nil},
  1010  					{3, nil, nil},
  1011  				},
  1012  			},
  1013  			{
  1014  				Query: "SELECT pk,i2,f FROM one_pk RIGHT JOIN niltable ON pk=i2 ORDER BY 2,3",
  1015  				Expected: []sql.Row{
  1016  					{nil, nil, nil},
  1017  					{nil, nil, nil},
  1018  					{nil, nil, 5.0},
  1019  					{2, int64(2), nil},
  1020  					{nil, int64(4), 4.0},
  1021  					{nil, int64(6), 6.0},
  1022  				},
  1023  			},
  1024  			{
  1025  				Query: "SELECT pk,i2,f FROM one_pk LEFT JOIN niltable ON pk=i2 AND f IS NOT NULL ORDER BY 1", // AND clause causes right table join miss
  1026  				Expected: []sql.Row{
  1027  					{0, nil, nil},
  1028  					{1, nil, nil},
  1029  					{2, nil, nil},
  1030  					{3, nil, nil},
  1031  				},
  1032  			},
  1033  			{
  1034  				Query: "SELECT pk,i2,f FROM one_pk RIGHT JOIN niltable ON pk=i2 and pk > 0 ORDER BY 2,3", // > 0 clause in join condition is ignored
  1035  				Expected: []sql.Row{
  1036  					{nil, nil, nil},
  1037  					{nil, nil, nil},
  1038  					{nil, nil, 5.0},
  1039  					{2, int64(2), nil},
  1040  					{nil, int64(4), 4.0},
  1041  					{nil, int64(6), 6.0},
  1042  				},
  1043  			},
  1044  			{
  1045  				Query: "SELECT pk,i,f FROM one_pk LEFT JOIN niltable ON pk=i WHERE f IS NULL AND pk < 2 ORDER BY 1",
  1046  				Expected: []sql.Row{
  1047  					{0, nil, nil},
  1048  					{1, 1, nil},
  1049  				},
  1050  			},
  1051  			{
  1052  				Query: "SELECT pk,i2,f FROM one_pk RIGHT JOIN niltable ON pk=i WHERE f IS NOT NULL ORDER BY 2,3",
  1053  				Expected: []sql.Row{
  1054  					{nil, nil, 5.0},
  1055  					{nil, int64(4), 4.0},
  1056  					{nil, int64(6), 6.0},
  1057  				},
  1058  			},
  1059  			{
  1060  				Query: "SELECT pk,i,f FROM one_pk LEFT JOIN niltable ON pk=i WHERE pk > 1 ORDER BY 1",
  1061  				Expected: []sql.Row{
  1062  					{2, 2, nil},
  1063  					{3, 3, nil},
  1064  				},
  1065  			},
  1066  			{
  1067  				Query: "SELECT pk,i,f FROM one_pk LEFT JOIN niltable ON pk=i WHERE c1 > 10 ORDER BY 1",
  1068  				Expected: []sql.Row{
  1069  					{2, 2, nil},
  1070  					{3, 3, nil},
  1071  				},
  1072  			},
  1073  			{
  1074  				Query: "SELECT pk,i,f FROM one_pk RIGHT JOIN niltable ON pk=i WHERE f IS NOT NULL ORDER BY 2,3",
  1075  				Expected: []sql.Row{
  1076  					{nil, 4, 4.0},
  1077  					{nil, 5, 5.0},
  1078  					{nil, 6, 6.0},
  1079  				},
  1080  			},
  1081  			{
  1082  				Query: "SELECT t1.i,t1.i2 FROM niltable t1 LEFT JOIN niltable t2 ON t1.i=t2.i2 WHERE t2.f IS NULL ORDER BY 1,2",
  1083  				Expected: []sql.Row{
  1084  					{1, nil},
  1085  					{2, 2},
  1086  					{3, nil},
  1087  					{5, nil},
  1088  				},
  1089  			},
  1090  			{
  1091  				Query: "SELECT pk,i,f FROM one_pk LEFT JOIN niltable ON pk=i WHERE i2 > 1 ORDER BY 1",
  1092  				Expected: []sql.Row{
  1093  					{2, 2, nil},
  1094  				},
  1095  			},
  1096  			{
  1097  				Query: "SELECT pk,i,f FROM one_pk LEFT JOIN niltable ON pk=i WHERE i > 1 ORDER BY 1",
  1098  				Expected: []sql.Row{
  1099  					{2, 2, nil},
  1100  					{3, 3, nil},
  1101  				},
  1102  			},
  1103  			{
  1104  				Query: "SELECT pk,i2,f FROM one_pk LEFT JOIN niltable ON pk=i WHERE i2 IS NOT NULL ORDER BY 1",
  1105  				Expected: []sql.Row{
  1106  					{2, int64(2), nil},
  1107  				},
  1108  			},
  1109  			{
  1110  				Query: "SELECT pk,i2,f FROM one_pk LEFT JOIN niltable ON pk=i2 WHERE pk > 1 ORDER BY 1",
  1111  				Expected: []sql.Row{
  1112  					{2, int64(2), nil},
  1113  					{3, nil, nil},
  1114  				},
  1115  			},
  1116  			{
  1117  				Query: "SELECT pk,i2,f FROM one_pk RIGHT JOIN niltable ON pk=i2 WHERE pk > 0 ORDER BY 2,3",
  1118  				Expected: []sql.Row{
  1119  					{2, int64(2), nil},
  1120  				},
  1121  			},
  1122  			{
  1123  				Query: "SELECT pk,pk1,pk2,one_pk.c1 AS foo, two_pk.c1 AS bar FROM one_pk JOIN two_pk ON one_pk.c1=two_pk.c1 ORDER BY 1,2,3",
  1124  				Expected: []sql.Row{
  1125  					{0, 0, 0, 0, 0},
  1126  					{1, 0, 1, 10, 10},
  1127  					{2, 1, 0, 20, 20},
  1128  					{3, 1, 1, 30, 30},
  1129  				},
  1130  			},
  1131  			{
  1132  				Query: "SELECT pk,pk1,pk2,one_pk.c1 AS foo,two_pk.c1 AS bar FROM one_pk JOIN two_pk ON one_pk.c1=two_pk.c1 WHERE one_pk.c1=10",
  1133  				Expected: []sql.Row{
  1134  					{1, 0, 1, 10, 10},
  1135  				},
  1136  			},
  1137  			{
  1138  				Query: "SELECT pk,pk1,pk2 FROM one_pk JOIN two_pk ON pk1-pk>0 AND pk2<1",
  1139  				Expected: []sql.Row{
  1140  					{0, 1, 0},
  1141  				},
  1142  			},
  1143  			{
  1144  				Query: "SELECT pk,pk1,pk2 FROM one_pk JOIN two_pk ORDER BY 1,2,3",
  1145  				Expected: []sql.Row{
  1146  					{0, 0, 0},
  1147  					{0, 0, 1},
  1148  					{0, 1, 0},
  1149  					{0, 1, 1},
  1150  					{1, 0, 0},
  1151  					{1, 0, 1},
  1152  					{1, 1, 0},
  1153  					{1, 1, 1},
  1154  					{2, 0, 0},
  1155  					{2, 0, 1},
  1156  					{2, 1, 0},
  1157  					{2, 1, 1},
  1158  					{3, 0, 0},
  1159  					{3, 0, 1},
  1160  					{3, 1, 0},
  1161  					{3, 1, 1},
  1162  				},
  1163  			},
  1164  			{
  1165  				Query: "SELECT a.pk,b.pk FROM one_pk a JOIN one_pk b ON a.pk = b.pk order by a.pk",
  1166  				Expected: []sql.Row{
  1167  					{0, 0},
  1168  					{1, 1},
  1169  					{2, 2},
  1170  					{3, 3},
  1171  				},
  1172  			},
  1173  			{
  1174  				Query: "SELECT a.pk,b.pk FROM one_pk a, one_pk b WHERE a.pk = b.pk order by a.pk",
  1175  				Expected: []sql.Row{
  1176  					{0, 0},
  1177  					{1, 1},
  1178  					{2, 2},
  1179  					{3, 3},
  1180  				},
  1181  			},
  1182  			{
  1183  				Query: "SELECT one_pk.pk,b.pk FROM one_pk JOIN one_pk b ON one_pk.pk = b.pk order by one_pk.pk",
  1184  				Expected: []sql.Row{
  1185  					{0, 0},
  1186  					{1, 1},
  1187  					{2, 2},
  1188  					{3, 3},
  1189  				},
  1190  			},
  1191  			{
  1192  				Query: "SELECT one_pk.pk,b.pk FROM one_pk, one_pk b WHERE one_pk.pk = b.pk order by one_pk.pk",
  1193  				Expected: []sql.Row{
  1194  					{0, 0},
  1195  					{1, 1},
  1196  					{2, 2},
  1197  					{3, 3},
  1198  				},
  1199  			},
  1200  			{
  1201  				Query: "select sum(x.i) + y.i from mytable as x, mytable as y where x.i = y.i GROUP BY x.i",
  1202  				Expected: []sql.Row{
  1203  					{float64(2)},
  1204  					{float64(4)},
  1205  					{float64(6)},
  1206  				},
  1207  			},
  1208  			{
  1209  				Query: `SELECT pk,tpk.pk1,tpk2.pk1,tpk.pk2,tpk2.pk2 FROM one_pk
  1210  						LEFT JOIN two_pk tpk ON one_pk.pk=tpk.pk1 AND one_pk.pk=tpk.pk2
  1211  						JOIN two_pk tpk2 ON tpk2.pk1=TPK.pk2 AND TPK2.pk2=tpk.pk1`,
  1212  				Expected: []sql.Row{
  1213  					{0, 0, 0, 0, 0},
  1214  					{1, 1, 1, 1, 1},
  1215  				},
  1216  			},
  1217  			{
  1218  				Query: `SELECT pk,nt.i,nt2.i FROM one_pk
  1219  						RIGHT JOIN niltable nt ON pk=nt.i
  1220  						RIGHT JOIN niltable nt2 ON pk=nt2.i - 1
  1221  						ORDER BY 3`,
  1222  				Expected: []sql.Row{
  1223  					{nil, nil, 1},
  1224  					{1, 1, 2},
  1225  					{2, 2, 3},
  1226  					{3, 3, 4},
  1227  					{nil, nil, 5},
  1228  					{nil, nil, 6},
  1229  				},
  1230  			},
  1231  			{
  1232  				Query: `SELECT pk,pk2,
  1233  							(SELECT opk.c5 FROM one_pk opk JOIN two_pk tpk ON pk=pk1 ORDER BY 1 LIMIT 1)
  1234  							FROM one_pk t1, two_pk t2 WHERE pk=1 AND pk2=1 ORDER BY 1,2`,
  1235  				Expected: []sql.Row{
  1236  					{1, 1, 4},
  1237  					{1, 1, 4},
  1238  				},
  1239  			},
  1240  			{
  1241  				Query: `SELECT pk,pk2,
  1242  							(SELECT opk.c5 FROM one_pk opk JOIN two_pk tpk ON opk.c5=tpk.c5 ORDER BY 1 LIMIT 1)
  1243  							FROM one_pk t1, two_pk t2 WHERE pk=1 AND pk2=1 ORDER BY 1,2`,
  1244  				Expected: []sql.Row{
  1245  					{1, 1, 4},
  1246  					{1, 1, 4},
  1247  				},
  1248  			},
  1249  			{
  1250  				Query: `SELECT /*+ JOIN_ORDER(mytable, othertable) */ s2, i2, i FROM mytable INNER JOIN (SELECT * FROM othertable) othertable ON i2 = i`,
  1251  				Expected: []sql.Row{
  1252  					{"third", 1, 1},
  1253  					{"second", 2, 2},
  1254  					{"first", 3, 3},
  1255  				},
  1256  			},
  1257  			{
  1258  				Query: `SELECT lefttable.i, righttable.s
  1259  			FROM (SELECT * FROM mytable) lefttable
  1260  			JOIN (SELECT * FROM mytable) righttable
  1261  			ON lefttable.i = righttable.i AND righttable.s = lefttable.s
  1262  			ORDER BY lefttable.i ASC`,
  1263  				Expected: []sql.Row{
  1264  					{1, "first row"},
  1265  					{2, "second row"},
  1266  					{3, "third row"},
  1267  				},
  1268  			},
  1269  			{
  1270  				Query: `SELECT a.* FROM mytable a, mytable b where a.i = b.i`,
  1271  				Expected: []sql.Row{
  1272  					{1, "first row"},
  1273  					{2, "second row"},
  1274  					{3, "third row"},
  1275  				},
  1276  			},
  1277  			{
  1278  				Query: `SELECT a.* FROM mytable a, mytable b where a.i = b.i OR a.i = 1`,
  1279  				Expected: []sql.Row{
  1280  					{1, "first row"},
  1281  					{1, "first row"},
  1282  					{1, "first row"},
  1283  					{2, "second row"},
  1284  					{3, "third row"},
  1285  				},
  1286  			},
  1287  			{
  1288  				Query: `SELECT a.* FROM mytable a, mytable b where NOT(a.i = b.i OR a.s = b.i)`,
  1289  				Expected: []sql.Row{
  1290  					{1, "first row"},
  1291  					{1, "first row"},
  1292  					{2, "second row"},
  1293  					{2, "second row"},
  1294  					{3, "third row"},
  1295  					{3, "third row"},
  1296  				},
  1297  			},
  1298  			{
  1299  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b where NOT(a.i = b.i OR a.s = b.i)`,
  1300  				Expected: []sql.Row{
  1301  					{1, "first row"},
  1302  					{1, "first row"},
  1303  					{2, "second row"},
  1304  					{2, "second row"},
  1305  					{3, "third row"},
  1306  					{3, "third row"},
  1307  				},
  1308  			},
  1309  			{
  1310  				Query: `SELECT a.* FROM mytable a, mytable b where a.i = b.s OR a.s = b.i IS FALSE`,
  1311  				Expected: []sql.Row{
  1312  					{1, "first row"},
  1313  					{2, "second row"},
  1314  					{3, "third row"},
  1315  					{1, "first row"},
  1316  					{2, "second row"},
  1317  					{3, "third row"},
  1318  					{1, "first row"},
  1319  					{2, "second row"},
  1320  					{3, "third row"},
  1321  				},
  1322  			},
  1323  			{
  1324  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b where a.i = b.s OR a.s = b.i IS FALSE`,
  1325  				Expected: []sql.Row{
  1326  					{1, "first row"},
  1327  					{2, "second row"},
  1328  					{3, "third row"},
  1329  					{1, "first row"},
  1330  					{2, "second row"},
  1331  					{3, "third row"},
  1332  					{1, "first row"},
  1333  					{2, "second row"},
  1334  					{3, "third row"},
  1335  				},
  1336  			},
  1337  			{
  1338  				Query: `SELECT a.* FROM mytable a, mytable b where a.i >= b.i`,
  1339  				Expected: []sql.Row{
  1340  					{1, "first row"},
  1341  					{2, "second row"},
  1342  					{2, "second row"},
  1343  					{3, "third row"},
  1344  					{3, "third row"},
  1345  					{3, "third row"},
  1346  				},
  1347  			},
  1348  			{
  1349  				Query:    `SELECT a.* FROM mytable a, mytable b where a.i = a.s`,
  1350  				Expected: []sql.Row{},
  1351  			},
  1352  			{
  1353  				Query: `SELECT a.* FROM mytable a, mytable b where a.i in (2, 432, 7)`,
  1354  				Expected: []sql.Row{
  1355  					{2, "second row"},
  1356  					{2, "second row"},
  1357  					{2, "second row"},
  1358  				},
  1359  			},
  1360  			{
  1361  				Query: `SELECT a.* FROM mytable a, mytable b, mytable c, mytable d where a.i = b.i AND b.i = c.i AND c.i = d.i AND c.i = 2`,
  1362  				Expected: []sql.Row{
  1363  					{2, "second row"},
  1364  				},
  1365  			},
  1366  			{
  1367  				Query: `SELECT a.* FROM mytable a, mytable b, mytable c, mytable d where a.i = b.i AND b.i = c.i AND (c.i = d.s OR c.i = 2)`,
  1368  				Expected: []sql.Row{
  1369  					{2, "second row"},
  1370  					{2, "second row"},
  1371  					{2, "second row"},
  1372  				},
  1373  			},
  1374  			{
  1375  				Query: `SELECT a.* FROM mytable a, mytable b, mytable c, mytable d where a.i = b.i AND b.s = c.s`,
  1376  				Expected: []sql.Row{
  1377  					{1, "first row"},
  1378  					{2, "second row"},
  1379  					{3, "third row"},
  1380  					{1, "first row"},
  1381  					{2, "second row"},
  1382  					{3, "third row"},
  1383  					{1, "first row"},
  1384  					{2, "second row"},
  1385  					{3, "third row"},
  1386  				},
  1387  			},
  1388  			{
  1389  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b where a.i = b.i`,
  1390  				Expected: []sql.Row{
  1391  					{1, "first row"},
  1392  					{2, "second row"},
  1393  					{3, "third row"},
  1394  				},
  1395  			},
  1396  			{
  1397  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b where a.i = b.i OR a.i = 1`,
  1398  				Expected: []sql.Row{
  1399  					{1, "first row"},
  1400  					{1, "first row"},
  1401  					{1, "first row"},
  1402  					{2, "second row"},
  1403  					{3, "third row"},
  1404  				},
  1405  			},
  1406  			{
  1407  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b where a.i >= b.i`,
  1408  				Expected: []sql.Row{
  1409  					{1, "first row"},
  1410  					{2, "second row"},
  1411  					{2, "second row"},
  1412  					{3, "third row"},
  1413  					{3, "third row"},
  1414  					{3, "third row"},
  1415  				},
  1416  			},
  1417  			{
  1418  				Query:    `SELECT a.* FROM mytable a CROSS JOIN mytable b where a.i = a.s`,
  1419  				Expected: []sql.Row{},
  1420  			},
  1421  			{
  1422  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b CROSS JOIN mytable c CROSS JOIN mytable d where a.i = b.i AND b.i = c.i AND c.i = d.i AND c.i = 2`,
  1423  				Expected: []sql.Row{
  1424  					{2, "second row"},
  1425  				},
  1426  			},
  1427  			{
  1428  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b CROSS JOIN mytable c CROSS JOIN mytable d where a.i = b.i AND b.i = c.i AND (c.i = d.s OR c.i = 2)`,
  1429  				Expected: []sql.Row{
  1430  					{2, "second row"},
  1431  					{2, "second row"},
  1432  					{2, "second row"}},
  1433  			},
  1434  			{
  1435  				Query: `SELECT a.* FROM mytable a CROSS JOIN mytable b CROSS JOIN mytable c CROSS JOIN mytable d where a.i = b.i AND b.s = c.s`,
  1436  				Expected: []sql.Row{
  1437  					{1, "first row"},
  1438  					{2, "second row"},
  1439  					{3, "third row"},
  1440  					{1, "first row"},
  1441  					{2, "second row"},
  1442  					{3, "third row"},
  1443  					{1, "first row"},
  1444  					{2, "second row"},
  1445  					{3, "third row"},
  1446  				},
  1447  			},
  1448  
  1449  			{
  1450  				Query: `SELECT * FROM mytable WHERE (
  1451  			EXISTS (SELECT * FROM mytable Alias1 JOIN mytable Alias2 WHERE Alias1.i = (mytable.i + 1))
  1452  			AND EXISTS (SELECT * FROM othertable Alias1 JOIN othertable Alias2 WHERE Alias1.i2 = (mytable.i + 2)));`,
  1453  				Expected: []sql.Row{{1, "first row"}},
  1454  			},
  1455  			{
  1456  				Query: `SELECT * FROM ab WHERE (
  1457  			EXISTS (SELECT * FROM ab Alias1 JOIN ab Alias2 WHERE Alias1.a = (ab.a + 1))
  1458  			AND EXISTS (SELECT * FROM xy Alias1 JOIN xy Alias2 WHERE Alias1.x = (ab.a + 2)));`,
  1459  				Expected: []sql.Row{
  1460  					{0, 2},
  1461  					{1, 2}},
  1462  			},
  1463  			{
  1464  				// verify that duplicate aliases in different subqueries are allowed
  1465  				Query: `SELECT * FROM mytable Alias0 WHERE (
  1466  				      	EXISTS (SELECT * FROM mytable Alias WHERE Alias.i = Alias0.i + 1)
  1467  				      	AND EXISTS (SELECT * FROM othertable Alias WHERE Alias.i2 = Alias0.i + 2));`,
  1468  				Expected: []sql.Row{{1, "first row"}},
  1469  			},
  1470  			{
  1471  				Query: `SELECT * FROM mytable
  1472  						WHERE
  1473    							i = (SELECT i2 FROM othertable alias1 WHERE i2 = 2) AND
  1474    							i+1 = (SELECT i2 FROM othertable alias1 WHERE i2 = 3);`,
  1475  				Expected: []sql.Row{{2, "second row"}},
  1476  			},
  1477  			{
  1478  				Query: `SELECT * FROM mytable WHERE (
  1479        					EXISTS (SELECT * FROM mytable Alias1 join mytable Alias2 WHERE Alias1.i = (mytable.i + 1))
  1480        					AND EXISTS (SELECT * FROM othertable Alias1 join othertable Alias2 WHERE Alias1.i2 = (mytable.i + 2)))`,
  1481  				Expected: []sql.Row{{1, "first row"}},
  1482  			},
  1483  		},
  1484  	},
  1485  	{
  1486  		name: "primary key range join",
  1487  		setup: [][]string{
  1488  			setup.MydbData[0],
  1489  			{
  1490  				"create table vals (val int primary key)",
  1491  				"create table ranges (min int primary key, max int, unique key(min,max))",
  1492  				"insert into vals values (0), (1), (2), (3), (4), (5), (6)",
  1493  				"insert into ranges values (0,2), (1,3), (2,4), (3,5), (4,6)",
  1494  			},
  1495  		},
  1496  		tests: rangeJoinOpTests,
  1497  	},
  1498  	{
  1499  		name: "keyless range join",
  1500  		setup: [][]string{
  1501  			setup.MydbData[0],
  1502  			{
  1503  				"create table vals (val int)",
  1504  				"create table ranges (min int, max int)",
  1505  				"insert into vals values (0), (1), (2), (3), (4), (5), (6)",
  1506  				"insert into ranges values (0,2), (1,3), (2,4), (3,5), (4,6)",
  1507  			},
  1508  		},
  1509  		tests: rangeJoinOpTests,
  1510  	},
  1511  	{
  1512  		name: "recursive range join",
  1513  		setup: [][]string{
  1514  			setup.MydbData[0],
  1515  		},
  1516  		tests: []JoinOpTests{{
  1517  			Query: "with recursive vals as (select 0 as val union all select val + 1 from vals where val < 6), " +
  1518  				"ranges as (select 0 as min, 2 as max union all select min+1, max+1 from ranges where max < 6) " +
  1519  				"select * from vals join ranges on val > min and val < max",
  1520  			Expected: []sql.Row{
  1521  				{1, 0, 2},
  1522  				{2, 1, 3},
  1523  				{3, 2, 4},
  1524  				{4, 3, 5},
  1525  				{5, 4, 6},
  1526  			},
  1527  		}},
  1528  	},
  1529  	{
  1530  		name: "where x not in (...)",
  1531  		setup: [][]string{
  1532  			setup.XyData[0],
  1533  		},
  1534  		tests: []JoinOpTests{
  1535  			{
  1536  				Query:    `SELECT * from xy_hasnull where y not in (SELECT b from ab_hasnull)`,
  1537  				Expected: []sql.Row{},
  1538  			},
  1539  			{
  1540  				Query:    `SELECT * from xy_hasnull where y not in (SELECT b from ab)`,
  1541  				Expected: []sql.Row{{1, 0}},
  1542  			},
  1543  			{
  1544  				Query:    `SELECT * from xy where y not in (SELECT b from ab_hasnull)`,
  1545  				Expected: []sql.Row{},
  1546  			},
  1547  			{
  1548  				Query:    `SELECT * from xy where null not in (SELECT b from ab)`,
  1549  				Expected: []sql.Row{},
  1550  			},
  1551  		},
  1552  	},
  1553  	{
  1554  		name: "multi-column merge join",
  1555  		setup: [][]string{
  1556  			setup.Pk_tablesData[0],
  1557  		},
  1558  		tests: []JoinOpTests{
  1559  			{
  1560  				Query:    `SELECT l.pk1, l.pk2, l.c1, r.pk1, r.pk2, r.c1 FROM two_pk l JOIN two_pk r ON l.pk1=r.pk1 AND l.pk2=r.pk2`,
  1561  				Expected: []sql.Row{{0, 0, 0, 0, 0, 0}, {0, 1, 10, 0, 1, 10}, {1, 0, 20, 1, 0, 20}, {1, 1, 30, 1, 1, 30}},
  1562  			},
  1563  			{
  1564  				Query:    `SELECT l.pk, r.pk FROM one_pk_two_idx l JOIN one_pk_two_idx r ON l.v1=r.v1 AND l.v2=r.v2`,
  1565  				Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7}},
  1566  			},
  1567  			{
  1568  				Query:    `SELECT l.pk, r.pk FROM one_pk_three_idx l JOIN one_pk_three_idx r ON l.v1=r.v1 AND l.v2=r.v2 AND l.pk=r.v1`,
  1569  				Expected: []sql.Row{{0, 0}, {0, 1}},
  1570  			},
  1571  			{
  1572  				Query:    `SELECT l.pk1, l.pk2, r.pk FROM two_pk l JOIN one_pk_three_idx r ON l.pk2=r.v1 WHERE l.pk1 = 1`,
  1573  				Expected: []sql.Row{{1, 0, 0}, {1, 0, 1}, {1, 0, 2}, {1, 0, 3}, {1, 1, 4}},
  1574  			},
  1575  			{
  1576  				Query:    `SELECT l.pk1, l.pk2, r.pk FROM two_pk l JOIN one_pk_three_idx r ON l.pk1=r.v1 WHERE l.pk2 = 1`,
  1577  				Expected: []sql.Row{{0, 1, 0}, {0, 1, 1}, {0, 1, 2}, {0, 1, 3}, {1, 1, 4}},
  1578  			},
  1579  			{
  1580  				Query:    `SELECT l.pk, r.pk FROM one_pk_three_idx l JOIN one_pk_three_idx r ON l.pk=r.v1 WHERE l.pk = 1`,
  1581  				Expected: []sql.Row{{1, 4}},
  1582  			},
  1583  		},
  1584  	},
  1585  }
  1586  
  1587  var rangeJoinOpTests = []JoinOpTests{
  1588  	{
  1589  		Query: "select * from vals join ranges on val between min and max",
  1590  		Expected: []sql.Row{
  1591  			{0, 0, 2},
  1592  			{1, 0, 2},
  1593  			{1, 1, 3},
  1594  			{2, 0, 2},
  1595  			{2, 1, 3},
  1596  			{2, 2, 4},
  1597  			{3, 1, 3},
  1598  			{3, 2, 4},
  1599  			{3, 3, 5},
  1600  			{4, 2, 4},
  1601  			{4, 3, 5},
  1602  			{4, 4, 6},
  1603  			{5, 3, 5},
  1604  			{5, 4, 6},
  1605  			{6, 4, 6},
  1606  		},
  1607  	},
  1608  	{
  1609  		Query: "select * from vals join ranges on val > min and val < max",
  1610  		Expected: []sql.Row{
  1611  			{1, 0, 2},
  1612  			{2, 1, 3},
  1613  			{3, 2, 4},
  1614  			{4, 3, 5},
  1615  			{5, 4, 6},
  1616  		},
  1617  	},
  1618  	{
  1619  		Query: "select * from vals join ranges on min < val and max > val",
  1620  		Expected: []sql.Row{
  1621  			{1, 0, 2},
  1622  			{2, 1, 3},
  1623  			{3, 2, 4},
  1624  			{4, 3, 5},
  1625  			{5, 4, 6},
  1626  		},
  1627  	},
  1628  	{
  1629  		Query: "select * from vals join ranges on val >= min and val < max",
  1630  		Expected: []sql.Row{
  1631  			{0, 0, 2},
  1632  			{1, 0, 2},
  1633  			{1, 1, 3},
  1634  			{2, 1, 3},
  1635  			{2, 2, 4},
  1636  			{3, 2, 4},
  1637  			{3, 3, 5},
  1638  			{4, 3, 5},
  1639  			{4, 4, 6},
  1640  			{5, 4, 6},
  1641  		},
  1642  	},
  1643  	{
  1644  		Query: "select * from vals join ranges on val > min and val <= max",
  1645  		Expected: []sql.Row{
  1646  			{1, 0, 2},
  1647  			{2, 0, 2},
  1648  			{2, 1, 3},
  1649  			{3, 1, 3},
  1650  			{3, 2, 4},
  1651  			{4, 2, 4},
  1652  			{4, 3, 5},
  1653  			{5, 3, 5},
  1654  			{5, 4, 6},
  1655  			{6, 4, 6},
  1656  		},
  1657  	},
  1658  	{
  1659  		Query: "select * from vals join ranges on val >= min and val <= max",
  1660  		Expected: []sql.Row{
  1661  			{0, 0, 2},
  1662  			{1, 0, 2},
  1663  			{1, 1, 3},
  1664  			{2, 0, 2},
  1665  			{2, 1, 3},
  1666  			{2, 2, 4},
  1667  			{3, 1, 3},
  1668  			{3, 2, 4},
  1669  			{3, 3, 5},
  1670  			{4, 2, 4},
  1671  			{4, 3, 5},
  1672  			{4, 4, 6},
  1673  			{5, 3, 5},
  1674  			{5, 4, 6},
  1675  			{6, 4, 6},
  1676  		},
  1677  	},
  1678  	{
  1679  		Query: "select * from vals left join ranges on val > min and val < max",
  1680  		Expected: []sql.Row{
  1681  			{0, nil, nil},
  1682  			{1, 0, 2},
  1683  			{2, 1, 3},
  1684  			{3, 2, 4},
  1685  			{4, 3, 5},
  1686  			{5, 4, 6},
  1687  			{6, nil, nil},
  1688  		},
  1689  	},
  1690  	{
  1691  		Query: "select * from ranges l join ranges r on l.min > r.min and l.min < r.max",
  1692  		Expected: []sql.Row{
  1693  			{1, 3, 0, 2},
  1694  			{2, 4, 1, 3},
  1695  			{3, 5, 2, 4},
  1696  			{4, 6, 3, 5},
  1697  		},
  1698  	},
  1699  	{
  1700  		Query: "select * from vals left join ranges r1 on val > r1.min and val < r1.max left join ranges r2 on r1.min > r2.min and r1.min < r2.max",
  1701  		Expected: []sql.Row{
  1702  			{0, nil, nil, nil, nil},
  1703  			{1, 0, 2, nil, nil},
  1704  			{2, 1, 3, 0, 2},
  1705  			{3, 2, 4, 1, 3},
  1706  			{4, 3, 5, 2, 4},
  1707  			{5, 4, 6, 3, 5},
  1708  			{6, nil, nil, nil, nil},
  1709  		},
  1710  	},
  1711  	{
  1712  		Query: "select * from (select vals.val * 2 as val from vals) as newVals join (select ranges.min * 2 as min, ranges.max * 2 as max from ranges) as newRanges on val > min and val < max;",
  1713  		Expected: []sql.Row{
  1714  			{2, 0, 4},
  1715  			{4, 2, 6},
  1716  			{6, 4, 8},
  1717  			{8, 6, 10},
  1718  			{10, 8, 12},
  1719  		},
  1720  	},
  1721  	{
  1722  		// This tests that the RangeHeapJoin node functions correctly even if its rows are iterated over multiple times.
  1723  		Query: "select * from (select 1 union select 2) as l left join (select * from vals join ranges on val > min and val < max) as r on max = max",
  1724  		Expected: []sql.Row{
  1725  			{1, 1, 0, 2},
  1726  			{1, 2, 1, 3},
  1727  			{1, 3, 2, 4},
  1728  			{1, 4, 3, 5},
  1729  			{1, 5, 4, 6},
  1730  			{2, 1, 0, 2},
  1731  			{2, 2, 1, 3},
  1732  			{2, 3, 2, 4},
  1733  			{2, 4, 3, 5},
  1734  			{2, 5, 4, 6},
  1735  		},
  1736  	},
  1737  	{
  1738  		Query: "select * from vals left join (select * from ranges where 0) as newRanges on val > min and val < max;",
  1739  		Expected: []sql.Row{
  1740  			{0, nil, nil},
  1741  			{1, nil, nil},
  1742  			{2, nil, nil},
  1743  			{3, nil, nil},
  1744  			{4, nil, nil},
  1745  			{5, nil, nil},
  1746  			{6, nil, nil},
  1747  		},
  1748  	},
  1749  }