From b1e20c043bf06eb7f4f2321708ea400b5bfe45df Mon Sep 17 00:00:00 2001 From: huby2358 Date: Thu, 26 Dec 2024 11:33:05 +0800 Subject: [PATCH] if delete can't rewrite to truncate table, use bind_delete make new plan --- pkg/sql/plan/bind_delete.go | 49 ++++++++++++++++++++++++++++++++----- pkg/sql/plan/build.go | 2 +- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/pkg/sql/plan/bind_delete.go b/pkg/sql/plan/bind_delete.go index 9980ec7e8ce4e..24771d5e7f33b 100644 --- a/pkg/sql/plan/bind_delete.go +++ b/pkg/sql/plan/bind_delete.go @@ -24,14 +24,40 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" ) -func (builder *QueryBuilder) bindDelete(stmt *tree.Delete, bindCtx *BindContext) (int32, error) { - if len(stmt.Tables) != 1 { - return 0, moerr.NewUnsupportedDML(builder.GetContext(), "delete from multiple tables") +func canDeleteRewriteToTruncate(ctx CompilerContext, dmlCtx DMLContext) (bool, error) { + accountId, err := ctx.GetAccountId() + if err != nil { + return false, err } - //FIXME: optimize truncate table? - if stmt.Where == nil && stmt.Limit == nil { - return 0, moerr.NewUnsupportedDML(builder.GetContext(), "rewrite to truncate table") + deleteOptToTruncate, err := checkDeleteOptToTruncate(ctx) + if err != nil { + return false, err + } + + if !deleteOptToTruncate { + return false, nil + } + + enabled, err := IsForeignKeyChecksEnabled(ctx) + if err != nil { + return false, err + } + + for i, tableDef := range dmlCtx.tableDefs { + if enabled && len(tableDef.RefChildTbls) > 0 || + tableDef.ViewSql != nil || + (dmlCtx.isClusterTable[i] && accountId != catalog.System_Account) || + dmlCtx.objRefs[i].PubInfo != nil { + return false, nil + } + } + return true, nil +} + +func (builder *QueryBuilder) bindDelete(ctx CompilerContext, stmt *tree.Delete, bindCtx *BindContext) (int32, error) { + if len(stmt.Tables) != 1 { + return 0, moerr.NewUnsupportedDML(builder.GetContext(), "delete from multiple tables") } aliasMap := make(map[string][2]string) @@ -45,6 +71,17 @@ func (builder *QueryBuilder) bindDelete(stmt *tree.Delete, bindCtx *BindContext) return 0, err } + //FIXME: optimize truncate table? + if stmt.Where == nil && stmt.Limit == nil { + var cantrucate bool + if cantrucate, err = canDeleteRewriteToTruncate(ctx, *dmlCtx); err != nil { + return 0, err + } + if cantrucate { + return 0, moerr.NewUnsupportedDML(builder.GetContext(), "rewrite to truncate table") + } + } + var selectList []tree.SelectExpr colName2Idx := make([]map[string]int32, len(stmt.Tables)) diff --git a/pkg/sql/plan/build.go b/pkg/sql/plan/build.go index 8361aa32f5c58..0cc77c5188b49 100644 --- a/pkg/sql/plan/build.go +++ b/pkg/sql/plan/build.go @@ -140,7 +140,7 @@ func bindAndOptimizeDeleteQuery(ctx CompilerContext, stmt *tree.Delete, isPrepar bindCtx.snapshot = ctx.GetSnapshot() } - rootId, err := builder.bindDelete(stmt, bindCtx) + rootId, err := builder.bindDelete(ctx, stmt, bindCtx) if err != nil { if err.(*moerr.Error).ErrorCode() == moerr.ErrUnsupportedDML { return buildDelete(stmt, ctx, isPrepareStmt)