From 47003ff937b0abfaa11a54554653235e231d93ea Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 26 Jul 2023 06:58:55 +0000 Subject: [PATCH] Delete Limit with start will return error because it's not supported by database (#1895) Fix #1894 Reviewed-on: https://gitea.com/xorm/xorm/pulls/1895 --- .gitea/workflows/test-cockroach.yml | 1 + integrations/session_delete_test.go | 58 +++++++++++++++++++++++++++++ internal/statements/delete.go | 3 ++ 3 files changed, 62 insertions(+) diff --git a/.gitea/workflows/test-cockroach.yml b/.gitea/workflows/test-cockroach.yml index 0ca18861..ba966dc9 100644 --- a/.gitea/workflows/test-cockroach.yml +++ b/.gitea/workflows/test-cockroach.yml @@ -43,6 +43,7 @@ jobs: TEST_COCKROACH_DBNAME: xorm_test TEST_COCKROACH_USERNAME: root TEST_COCKROACH_PASSWORD: + IGNORE_TEST_DELETE_LIMIT: true run: sleep 20 && make test-cockroach services: diff --git a/integrations/session_delete_test.go b/integrations/session_delete_test.go index 680c3215..1ed3e706 100644 --- a/integrations/session_delete_test.go +++ b/integrations/session_delete_test.go @@ -5,6 +5,7 @@ package integrations import ( + "os" "testing" "time" @@ -70,6 +71,63 @@ func TestDelete(t *testing.T) { assert.False(t, has) } +func TestDeleteLimit(t *testing.T) { + assert.NoError(t, PrepareEngine()) + + if testEngine.Dialect().URI().DBType == schemas.MSSQL || os.Getenv("IGNORE_TEST_DELETE_LIMIT") == "true" { + t.Skip() + return + } + + type UserinfoDeleteLimit struct { + Uid int64 `xorm:"id pk not null autoincr"` + IsMan bool + } + + assert.NoError(t, testEngine.Sync2(new(UserinfoDeleteLimit))) + + session := testEngine.NewSession() + defer session.Close() + + var err error + if testEngine.Dialect().URI().DBType == schemas.MSSQL { + err = session.Begin() + assert.NoError(t, err) + _, err = session.Exec("SET IDENTITY_INSERT userinfo_delete_limit ON") + assert.NoError(t, err) + } + + user := UserinfoDeleteLimit{Uid: 1, IsMan: true} + cnt, err := session.Insert(&user) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + user2 := UserinfoDeleteLimit{Uid: 2} + cnt, err = session.Insert(&user2) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + if testEngine.Dialect().URI().DBType == schemas.MSSQL { + err = session.Commit() + assert.NoError(t, err) + } + + cnt, err = testEngine.Limit(1, 1).Delete(&UserinfoDeleteLimit{}) + assert.Error(t, err) + assert.EqualValues(t, 0, cnt) + + cnt, err = testEngine.Limit(1).Desc("id").Delete(&UserinfoDeleteLimit{}) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var users []UserinfoDeleteLimit + err = testEngine.Find(&users) + assert.NoError(t, err) + assert.EqualValues(t, 1, len(users)) + assert.EqualValues(t, 1, users[0].Uid) + assert.EqualValues(t, true, users[0].IsMan) +} + func TestDeleted(t *testing.T) { assert.NoError(t, PrepareEngine()) diff --git a/internal/statements/delete.go b/internal/statements/delete.go index a77cf862..6e859399 100644 --- a/internal/statements/delete.go +++ b/internal/statements/delete.go @@ -20,6 +20,9 @@ func (statement *Statement) writeDeleteOrder(w *builder.BytesWriter) error { } if statement.LimitN != nil && *statement.LimitN > 0 { + if statement.Start > 0 { + return fmt.Errorf("Delete with Limit start is unsupported") + } limitNValue := *statement.LimitN if _, err := fmt.Fprintf(w, " LIMIT %d", limitNValue); err != nil { return err