db: only strict schemas

This commit is contained in:
Asdine El Hrychy
2024-02-17 14:25:05 +04:00
parent ef91bb4a3b
commit fc051f7cf9
248 changed files with 6732 additions and 13741 deletions

View File

@@ -6,7 +6,6 @@ import (
"github.com/chaisql/chai/internal/expr"
"github.com/chaisql/chai/internal/expr/functions"
"github.com/chaisql/chai/internal/object"
"github.com/chaisql/chai/internal/query"
"github.com/chaisql/chai/internal/query/statement"
"github.com/chaisql/chai/internal/sql/parser"
@@ -30,23 +29,16 @@ func TestParserSelect(t *testing.T) {
stream.New(rows.Project(testutil.ParseNamedExpr(t, "1"))),
true, false,
},
{"NoTableWithTuple", "SELECT (1, 2)",
stream.New(rows.Project(testutil.ParseNamedExpr(t, "[1, 2]"))),
true, false,
},
{"NoTableWithBrackets", "SELECT [1, 2]",
stream.New(rows.Project(testutil.ParseNamedExpr(t, "[1, 2]"))),
true, false,
},
{"NoTableWithINOperator", "SELECT 1 in (1, 2), 3",
stream.New(rows.Project(
testutil.ParseNamedExpr(t, "1 IN [1, 2]"),
testutil.ParseNamedExpr(t, "1 IN (1, 2)"),
testutil.ParseNamedExpr(t, "3"),
)),
true, false,
},
{"NoCond", "SELECT * FROM test",
stream.New(table.Scan("test")),
stream.New(table.Scan("test")).Pipe(rows.Project(expr.Wildcard{})),
true, false,
},
{"Multiple Wildcards", "SELECT *, * FROM test",
@@ -57,10 +49,6 @@ func TestParserSelect(t *testing.T) {
stream.New(table.Scan("test")).Pipe(rows.Project(testutil.ParseNamedExpr(t, "a"), testutil.ParseNamedExpr(t, "b"))),
true, false,
},
{"WithFieldsWithQuotes", "SELECT `long \"path\"` FROM test",
stream.New(table.Scan("test")).Pipe(rows.Project(testutil.ParseNamedExpr(t, "`long \"path\"`", "long \"path\""))),
true, false,
},
{"WithAlias", "SELECT a AS A, b FROM test",
stream.New(table.Scan("test")).Pipe(rows.Project(testutil.ParseNamedExpr(t, "a", "A"), testutil.ParseNamedExpr(t, "b"))),
true, false,
@@ -75,50 +63,57 @@ func TestParserSelect(t *testing.T) {
},
{"WithCond", "SELECT * FROM test WHERE age = 10",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))),
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.Project(expr.Wildcard{})),
true, false,
},
{"WithGroupBy", "SELECT a.b.c FROM test WHERE age = 10 GROUP BY a.b.c",
{"WithGroupBy", "SELECT a FROM test WHERE age = 10 GROUP BY a",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.TempTreeSort(parser.MustParseExpr("a.b.c"))).
Pipe(rows.GroupAggregate(parser.MustParseExpr("a.b.c"))).
Pipe(rows.Project(&expr.NamedExpr{ExprName: "a.b.c", Expr: expr.Path(object.NewPath("a.b.c"))})),
Pipe(rows.TempTreeSort(parser.MustParseExpr("a"))).
Pipe(rows.GroupAggregate(parser.MustParseExpr("a"))).
Pipe(rows.Project(&expr.NamedExpr{ExprName: "a", Expr: expr.Column("a")})),
true, false,
},
{"WithOrderBy", "SELECT * FROM test WHERE age = 10 ORDER BY a.b.c",
{"WithOrderBy", "SELECT * FROM test WHERE age = 10 ORDER BY a",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.TempTreeSort(testutil.ParsePath(t, "a.b.c"))),
Pipe(rows.Project(expr.Wildcard{})).
Pipe(rows.TempTreeSort(expr.Column("a"))),
true, false,
},
{"WithOrderBy ASC", "SELECT * FROM test WHERE age = 10 ORDER BY a.b.c ASC",
{"WithOrderBy ASC", "SELECT * FROM test WHERE age = 10 ORDER BY a ASC",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.TempTreeSort(testutil.ParsePath(t, "a.b.c"))),
Pipe(rows.Project(expr.Wildcard{})).
Pipe(rows.TempTreeSort(expr.Column("a"))),
true, false,
},
{"WithOrderBy DESC", "SELECT * FROM test WHERE age = 10 ORDER BY a.b.c DESC",
{"WithOrderBy DESC", "SELECT * FROM test WHERE age = 10 ORDER BY a DESC",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.TempTreeSortReverse(testutil.ParsePath(t, "a.b.c"))),
Pipe(rows.Project(expr.Wildcard{})).
Pipe(rows.TempTreeSortReverse(expr.Column("a"))),
true, false,
},
{"WithLimit", "SELECT * FROM test WHERE age = 10 LIMIT 20",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.Project(expr.Wildcard{})).
Pipe(rows.Take(parser.MustParseExpr("20"))),
true, false,
},
{"WithOffset", "SELECT * FROM test WHERE age = 10 OFFSET 20",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.Project(expr.Wildcard{})).
Pipe(rows.Skip(parser.MustParseExpr("20"))),
true, false,
},
{"WithLimitThenOffset", "SELECT * FROM test WHERE age = 10 LIMIT 10 OFFSET 20",
stream.New(table.Scan("test")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.Project(expr.Wildcard{})).
Pipe(rows.Skip(parser.MustParseExpr("20"))).
Pipe(rows.Take(parser.MustParseExpr("10"))),
true, false,
@@ -135,16 +130,18 @@ func TestParserSelect(t *testing.T) {
false, false},
{"WithUnionAll", "SELECT * FROM test1 UNION ALL SELECT * FROM test2",
stream.New(stream.Concat(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
stream.New(table.Scan("test1")).Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
{"CondWithUnionAll", "SELECT * FROM test1 WHERE age = 10 UNION ALL SELECT * FROM test2",
stream.New(stream.Concat(
stream.New(table.Scan("test1")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))),
stream.New(table.Scan("test2")),
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
@@ -162,45 +159,57 @@ func TestParserSelect(t *testing.T) {
},
{"WithUnionAllAndOrderBy", "SELECT * FROM test1 UNION ALL SELECT * FROM test2 ORDER BY a",
stream.New(stream.Concat(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
)).Pipe(rows.TempTreeSort(testutil.ParsePath(t, "a"))),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.TempTreeSort(expr.Column("a"))),
true, false,
},
{"WithUnionAllAndLimit", "SELECT * FROM test1 UNION ALL SELECT * FROM test2 LIMIT 10",
stream.New(stream.Concat(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.Take(parser.MustParseExpr("10"))),
true, false,
},
{"WithUnionAllAndOffset", "SELECT * FROM test1 UNION ALL SELECT * FROM test2 OFFSET 20",
stream.New(stream.Concat(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.Skip(parser.MustParseExpr("20"))),
true, false,
},
{"WithUnionAllAndOrderByAndLimitAndOffset", "SELECT * FROM test1 UNION ALL SELECT * FROM test2 ORDER BY a LIMIT 10 OFFSET 20",
stream.New(stream.Concat(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
)).Pipe(rows.TempTreeSort(testutil.ParsePath(t, "a"))).Pipe(rows.Skip(parser.MustParseExpr("20"))).Pipe(rows.Take(parser.MustParseExpr("10"))),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.TempTreeSort(expr.Column("a"))).Pipe(rows.Skip(parser.MustParseExpr("20"))).Pipe(rows.Take(parser.MustParseExpr("10"))),
true, false,
},
{"WithUnion", "SELECT * FROM test1 UNION SELECT * FROM test2",
stream.New(stream.Union(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
{"CondWithUnion", "SELECT * FROM test1 WHERE age = 10 UNION SELECT * FROM test2",
stream.New(stream.Union(
stream.New(table.Scan("test1")).
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))),
stream.New(table.Scan("test2")),
Pipe(rows.Filter(parser.MustParseExpr("age = 10"))).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
@@ -218,69 +227,91 @@ func TestParserSelect(t *testing.T) {
},
{"WithUnionAndOrderBy", "SELECT * FROM test1 UNION SELECT * FROM test2 ORDER BY a",
stream.New(stream.Union(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
)).Pipe(rows.TempTreeSort(testutil.ParsePath(t, "a"))),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.TempTreeSort(expr.Column("a"))),
true, false,
},
{"WithUnionAndLimit", "SELECT * FROM test1 UNION SELECT * FROM test2 LIMIT 10",
stream.New(stream.Union(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.Take(parser.MustParseExpr("10"))),
true, false,
},
{"WithUnionAndOffset", "SELECT * FROM test1 UNION SELECT * FROM test2 OFFSET 20",
stream.New(stream.Union(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.Skip(parser.MustParseExpr("20"))),
true, false,
},
{"WithUnionAndOrderByAndLimitAndOffset", "SELECT * FROM test1 UNION SELECT * FROM test2 ORDER BY a LIMIT 10 OFFSET 20",
stream.New(stream.Union(
stream.New(table.Scan("test1")),
stream.New(table.Scan("test2")),
)).Pipe(rows.TempTreeSort(testutil.ParsePath(t, "a"))).Pipe(rows.Skip(parser.MustParseExpr("20"))).Pipe(rows.Take(parser.MustParseExpr("10"))),
stream.New(table.Scan("test1")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("test2")).
Pipe(rows.Project(expr.Wildcard{})),
)).Pipe(rows.TempTreeSort(expr.Column("a"))).Pipe(rows.Skip(parser.MustParseExpr("20"))).Pipe(rows.Take(parser.MustParseExpr("10"))),
true, false,
},
{"WithMultipleCompoundOps/1", "SELECT * FROM a UNION ALL SELECT * FROM b UNION ALL SELECT * FROM c",
stream.New(stream.Concat(
stream.New(table.Scan("a")),
stream.New(table.Scan("b")),
stream.New(table.Scan("c")),
stream.New(table.Scan("a")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("b")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("c")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
{"WithMultipleCompoundOps/2", "SELECT * FROM a UNION ALL SELECT * FROM b UNION SELECT * FROM c",
stream.New(stream.Union(
stream.New(stream.Concat(
stream.New(table.Scan("a")),
stream.New(table.Scan("b")),
stream.New(table.Scan("a")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("b")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("c")),
stream.New(table.Scan("c")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
{"WithMultipleCompoundOps/2", "SELECT * FROM a UNION ALL SELECT * FROM b UNION ALL SELECT * FROM c UNION SELECT * FROM d",
stream.New(stream.Union(
stream.New(stream.Concat(
stream.New(table.Scan("a")),
stream.New(table.Scan("b")),
stream.New(table.Scan("c")),
stream.New(table.Scan("a")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("b")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("c")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("d")),
stream.New(table.Scan("d")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
{"WithMultipleCompoundOps/3", "SELECT * FROM a UNION ALL SELECT * FROM b UNION SELECT * FROM c UNION SELECT * FROM d",
stream.New(stream.Union(
stream.New(stream.Concat(
stream.New(table.Scan("a")),
stream.New(table.Scan("b")),
stream.New(table.Scan("a")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("b")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("c")),
stream.New(table.Scan("d")),
stream.New(table.Scan("c")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("d")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
@@ -288,12 +319,16 @@ func TestParserSelect(t *testing.T) {
stream.New(stream.Concat(
stream.New(stream.Union(
stream.New(stream.Concat(
stream.New(table.Scan("a")),
stream.New(table.Scan("b")),
stream.New(table.Scan("a")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("b")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("c")),
stream.New(table.Scan("c")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("d")),
stream.New(table.Scan("d")).
Pipe(rows.Project(expr.Wildcard{})),
)),
true, false,
},
@@ -301,10 +336,13 @@ func TestParserSelect(t *testing.T) {
stream.New(stream.Concat(
stream.New(stream.Union(
stream.New(stream.Concat(
stream.New(table.Scan("a")),
stream.New(table.Scan("b")),
stream.New(table.Scan("a")).
Pipe(rows.Project(expr.Wildcard{})),
stream.New(table.Scan("b")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("c")),
stream.New(table.Scan("c")).
Pipe(rows.Project(expr.Wildcard{})),
)),
stream.New(table.Scan("d")).Pipe(rows.Project(testutil.ParseNamedExpr(t, "NEXT VALUE FOR foo"))),
)),
@@ -319,13 +357,13 @@ func TestParserSelect(t *testing.T) {
db := testutil.NewTestDB(t)
testutil.MustExec(t, db, nil, `
CREATE TABLE test;
CREATE TABLE test1;
CREATE TABLE test2;
CREATE TABLE a;
CREATE TABLE b;
CREATE TABLE c;
CREATE TABLE d;
CREATE TABLE test(a TEXT, b TEXT, age int);
CREATE TABLE test1(age INT, a INT);
CREATE TABLE test2(age INT, a INT);
CREATE TABLE a(age INT, a INT);
CREATE TABLE b(age INT, a INT);
CREATE TABLE c(age INT, a INT);
CREATE TABLE d(age INT, a INT);
`,
)
@@ -346,6 +384,6 @@ func TestParserSelect(t *testing.T) {
func BenchmarkSelect(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = parser.ParseQuery("SELECT a, b.c[100].d AS `foo` FROM `some table` WHERE d.e[100] >= 12 AND c.d IN ([1, true], [2, false]) GROUP BY d.e[0] LIMIT 10 + 10 OFFSET 20 - 20 ORDER BY d DESC")
_, _ = parser.ParseQuery("SELECT a, b AS `foo` FROM `some table` WHERE d.e[100] >= 12 AND c.d IN ([1, true], [2, false]) GROUP BY d.e[0] LIMIT 10 + 10 OFFSET 20 - 20 ORDER BY d DESC")
}
}