Files
2026-07-13 12:32:25 +08:00

275 lines
6.7 KiB
Go
Executable File

package _go
import (
"testing"
"github.com/dolthub/go-mysql-server/sql"
)
func TestSubqueries(t *testing.T) {
RunScripts(t, []ScriptTest{
{
Name: "Subselect",
SetUpScript: []string{
`CREATE TABLE test (id INT);`,
`INSERT INTO test VALUES (1), (3), (2);`,
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT * FROM test WHERE id = (SELECT 2);`,
Expected: []sql.Row{
{int32(2)},
},
},
{
Query: `SELECT *, (SELECT id from test where id = 2) FROM test order by id;`,
Expected: []sql.Row{
{1, 2},
{2, 2},
{3, 2},
},
},
{
Query: `SELECT *, (SELECT id from test t2 where t2.id = test.id) FROM test order by id;`,
Expected: []sql.Row{
{1, 1},
{2, 2},
{3, 3},
},
},
},
},
{
Name: "IN",
SetUpScript: []string{
`CREATE TABLE test (id INT);`,
`INSERT INTO test VALUES (1), (3), (2);`,
`CREATE TABLE test2 (id INT, test_id INT, txt text);`,
`INSERT INTO test2 VALUES (1, 1, 'foo'), (2, 10, 'bar'), (3, 2, 'baz');`,
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT * FROM test WHERE id IN (SELECT * FROM test WHERE id = 2);`,
Expected: []sql.Row{{int32(2)}},
},
{
Query: `SELECT * FROM test WHERE id IN (SELECT id FROM test WHERE id = 3);`,
Expected: []sql.Row{{int32(3)}},
},
{
Query: `SELECT * FROM test WHERE id IN (SELECT * FROM test WHERE id > 0);`,
Expected: []sql.Row{{int32(1)}, {int32(3)}, {int32(2)}},
},
{
Query: `SELECT * FROM test2 WHERE test_id IN (SELECT * FROM test WHERE id = 2);`,
Expected: []sql.Row{{int32(3), int32(2), "baz"}},
},
{
Query: `SELECT * FROM test2 WHERE test_id IN (SELECT * FROM test WHERE id > 0);`,
Expected: []sql.Row{
{int32(1), int32(1), "foo"},
{int32(3), int32(2), "baz"},
},
},
{
Query: `SELECT id FROM test2 WHERE (2, 10) IN (SELECT id, test_id FROM test2 WHERE id > 0);`,
Skip: true, // won't pass until we have a doltgres tuple type to match against for equality funcs
Expected: []sql.Row{
{1}, {2}, {3},
},
},
{
Query: `SELECT id FROM test2 WHERE (id, test_id) IN (SELECT id, test_id FROM test2 WHERE id > 0);`,
Skip: true, // won't pass until we have a doltgres tuple type to match against for equality funcs
Expected: []sql.Row{
{2},
},
},
},
},
{
Name: "subquery equality",
SetUpScript: []string{
`CREATE TABLE test (id INT, c varchar);`,
`INSERT INTO test VALUES (1, 'a'), (2, 'b'), (3, 'b');`,
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT * FROM test WHERE id = (SELECT id from test where id = 2);`,
Expected: []sql.Row{{int32(2), "b"}},
},
{
Skip: true, // panic in equality func
Query: `SELECT (SELECT id from test where id = 2) = (SELECT id from test where id = 2);`,
Expected: []sql.Row{{"t"}},
},
{
Skip: true, // panic in equality func
Query: `SELECT (SELECT c from test where id = 2) = (SELECT c from test where id = 3);`,
Expected: []sql.Row{{"t"}},
},
{
Skip: true, // panic in equality func
Query: `SELECT (SELECT c from test where id = 1) = (SELECT c from test where id = 2);`,
Expected: []sql.Row{{"f"}},
},
},
},
{
Name: "array flatten",
SetUpScript: []string{
`CREATE TABLE test (id INT, c varchar);`,
`INSERT INTO test VALUES (1, 'a'), (2, 'b'), (3, 'c');`,
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT ARRAY(SELECT id FROM test order by 1);`,
Expected: []sql.Row{
{"{1,2,3}"},
},
},
{
Query: `SELECT ARRAY(SELECT c FROM test order by id limit 1);`,
Expected: []sql.Row{
{"{a}"},
},
},
{
Query: `SELECT ARRAY(SELECT c FROM test order by id desc);`,
Expected: []sql.Row{
{"{c,b,a}"},
},
},
{
Query: `SELECT ARRAY(SELECT id, id FROM test order by 1);`,
ExpectedErr: "only a single column subquery is supported",
},
{
Query: `SELECT array_to_string(ARRAY(SELECT id FROM test order by 1), ',')`,
Expected: []sql.Row{
{"1,2,3"},
},
},
},
},
})
}
func TestSubqueryJoins(t *testing.T) {
RunScripts(t, []ScriptTest{
{
Name: "subquery join",
SetUpScript: []string{
"CREATE TABLE t1 (a int primary key);",
"CREATE TABLE t2 (b int primary key);",
"INSERT INTO t1 VALUES (1), (2), (3);",
"INSERT INTO t2 VALUES (2), (3), (4);",
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT
s1.a FROM (SELECT a from t1) s1
INNER JOIN t2 q1
ON q1.b = s1.a
ORDER BY 1;`,
Expected: []sql.Row{
{2},
{3},
},
},
},
},
{
Name: "subquery join with aliased column",
SetUpScript: []string{
"CREATE TABLE t1 (a int primary key);",
"CREATE TABLE t2 (b int primary key);",
"INSERT INTO t1 VALUES (1), (2), (3);",
"INSERT INTO t2 VALUES (2), (3), (4);",
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT
s1.c FROM (SELECT a as c from t1) s1
INNER JOIN t2 q1
ON q1.b = s1.c
ORDER BY 1;`,
Expected: []sql.Row{
{2},
{3},
},
},
},
},
{
Name: "subquery join with column renames",
SetUpScript: []string{
"CREATE TABLE t1 (a int primary key, b int);",
"CREATE TABLE t2 (c int primary key);",
"INSERT INTO t1 VALUES (1,10), (2,20), (3,30);",
"INSERT INTO t2 VALUES (2), (3), (4);",
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT
s1.d FROM (SELECT b as f, a as g from t1) s1(d,e)
INNER JOIN t2 q1
ON q1.c = s1.e
ORDER BY 1;`,
Expected: []sql.Row{
{20},
{30},
},
},
},
},
})
}
func TestExistSubquery(t *testing.T) {
RunScripts(t, []ScriptTest{
{
Name: "basic case",
SetUpScript: []string{
`CREATE TABLE test (id INT PRIMARY KEY);`,
`INSERT INTO test VALUES (1), (3), (2);`,
},
Assertions: []ScriptTestAssertion{
{
Query: `SELECT * FROM test WHERE EXISTS (SELECT 123);`,
Expected: []sql.Row{
{1},
{2},
{3},
},
},
{
Query: `SELECT * FROM test WHERE NOT EXISTS (SELECT 123);`,
Expected: []sql.Row{},
},
{
Query: `SELECT 123 WHERE EXISTS (SELECT * FROM test);`,
Expected: []sql.Row{
{123},
},
},
{
Query: `SELECT 123 WHERE EXISTS (SELECT * FROM test WHERE id > 10);`,
Expected: []sql.Row{},
},
{
Query: `SELECT 123 WHERE NOT EXISTS (SELECT * FROM test);`,
Expected: []sql.Row{},
},
{
Query: `SELECT 123 WHERE NOT EXISTS (SELECT * FROM test WHERE id > 10);`,
Expected: []sql.Row{
{123},
},
},
},
},
})
}