package parser_test import ( "testing" "github.com/chaisql/chai/internal/expr" "github.com/chaisql/chai/internal/query/statement" "github.com/chaisql/chai/internal/sql/parser" "github.com/chaisql/chai/internal/stream" "github.com/chaisql/chai/internal/stream/rows" "github.com/chaisql/chai/internal/stream/table" "github.com/chaisql/chai/internal/testutil" "github.com/stretchr/testify/require" ) func TestParserDelete(t *testing.T) { db, tx, cleanup := testutil.NewTestTx(t) defer cleanup() testutil.MustExec(t, db, tx, "CREATE TABLE test(age int primary key)") parseExpr := func(s string) expr.Expr { e := parser.MustParseExpr(s) err := statement.BindExpr(&statement.Context{DB: db, Conn: tx.Connection()}, "test", e) require.NoError(t, err) return e } tests := []struct { name string s string expected *stream.Stream }{ {"NoCond", "DELETE FROM test", stream.New(table.Scan("test")).Pipe(table.Delete("test")). Pipe(stream.Discard())}, {"WithCond", "DELETE FROM test WHERE age = 10", stream.New(table.Scan("test")). Pipe(rows.Filter(parseExpr("age = 10"))). Pipe(table.Delete("test")). Pipe(stream.Discard()), }, {"WithOffset", "DELETE FROM test WHERE age = 10 OFFSET 20", stream.New(table.Scan("test")). Pipe(rows.Filter(parseExpr("age = 10"))). Pipe(rows.Skip(parseExpr("20"))). Pipe(table.Delete("test")). Pipe(stream.Discard()), }, {"WithLimit", "DELETE FROM test LIMIT 10", stream.New(table.Scan("test")). Pipe(rows.Take(parseExpr("10"))). Pipe(table.Delete("test")). Pipe(stream.Discard()), }, {"WithOrderByThenOffset", "DELETE FROM test WHERE age = 10 ORDER BY age OFFSET 20", stream.New(table.Scan("test")). Pipe(rows.Filter(parseExpr("age = 10"))). Pipe(rows.TempTreeSort(parseExpr("age"))). Pipe(rows.Skip(parseExpr("20"))). Pipe(table.Delete("test")). Pipe(stream.Discard()), }, {"WithOrderByThenLimitThenOffset", "DELETE FROM test WHERE age = 10 ORDER BY age LIMIT 10 OFFSET 20", stream.New(table.Scan("test")). Pipe(rows.Filter(parseExpr("age = 10"))). Pipe(rows.TempTreeSort(parseExpr("age"))). Pipe(rows.Skip(parseExpr("20"))). Pipe(rows.Take(parseExpr("10"))). Pipe(table.Delete("test")). Pipe(stream.Discard()), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { stmts, err := parser.ParseQuery(test.s) require.NoError(t, err) require.Len(t, stmts, 1) stmt, err := stmts[0].(statement.Preparer).Prepare(&statement.Context{ DB: db, Conn: tx.Connection(), }) require.NoError(t, err) require.Equal(t, test.expected.String(), stmt.(*statement.DeleteStmt).Stream.String()) }) } }