github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/build_delete.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plan 16 17 import ( 18 "time" 19 20 "github.com/matrixorigin/matrixone/pkg/pb/plan" 21 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 22 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 23 v2 "github.com/matrixorigin/matrixone/pkg/util/metric/v2" 24 ) 25 26 func buildDelete(stmt *tree.Delete, ctx CompilerContext, isPrepareStmt bool) (*Plan, error) { 27 start := time.Now() 28 defer func() { 29 v2.TxnStatementBuildDeleteHistogram.Observe(time.Since(start).Seconds()) 30 }() 31 aliasMap := make(map[string][2]string) 32 for _, tbl := range stmt.TableRefs { 33 getAliasToName(ctx, tbl, "", aliasMap) 34 } 35 tblInfo, err := getDmlTableInfo(ctx, stmt.Tables, stmt.With, aliasMap, "delete") 36 if err != nil { 37 return nil, err 38 } 39 builder := NewQueryBuilder(plan.Query_SELECT, ctx, isPrepareStmt) 40 41 queryBindCtx := NewBindContext(builder, nil) 42 lastNodeId, err := deleteToSelect(builder, queryBindCtx, stmt, true, tblInfo) 43 if err != nil { 44 return nil, err 45 } 46 sourceStep := builder.appendStep(lastNodeId) 47 query, err := builder.createQuery() 48 if err != nil { 49 return nil, err 50 } 51 builder.qry.Steps = append(builder.qry.Steps[:sourceStep], builder.qry.Steps[sourceStep+1:]...) 52 53 // append sink node 54 lastNodeId = appendSinkNode(builder, queryBindCtx, lastNodeId) 55 sourceStep = builder.appendStep(lastNodeId) 56 57 allDelTableIDs := make(map[uint64]struct{}) 58 for _, tableDef := range tblInfo.tableDefs { 59 allDelTableIDs[tableDef.TblId] = struct{}{} 60 } 61 62 allDelTables := make(map[FkReferKey]struct{}) 63 for i, tableDef := range tblInfo.tableDefs { 64 allDelTables[FkReferKey{Db: tblInfo.objRef[i].SchemaName, Tbl: tableDef.Name}] = struct{}{} 65 } 66 // append delete plans 67 beginIdx := 0 68 // needLockTable := !tblInfo.isMulti && stmt.Where == nil && stmt.Limit == nil 69 // todo will do not lock table now. 70 isDeleteWithoutFilters := !tblInfo.isMulti && stmt.Where == nil && stmt.Limit == nil 71 needLockTable := isDeleteWithoutFilters 72 for i, tableDef := range tblInfo.tableDefs { 73 deleteBindCtx := NewBindContext(builder, nil) 74 delPlanCtx := getDmlPlanCtx() 75 delPlanCtx.objRef = tblInfo.objRef[i] 76 delPlanCtx.tableDef = tableDef 77 delPlanCtx.beginIdx = beginIdx 78 delPlanCtx.sourceStep = sourceStep 79 delPlanCtx.isMulti = tblInfo.isMulti 80 delPlanCtx.needAggFilter = tblInfo.needAggFilter 81 delPlanCtx.updateColLength = 0 82 delPlanCtx.rowIdPos = getRowIdPos(tableDef) 83 delPlanCtx.allDelTableIDs = allDelTableIDs 84 delPlanCtx.allDelTables = allDelTables 85 delPlanCtx.lockTable = needLockTable 86 delPlanCtx.isDeleteWithoutFilters = isDeleteWithoutFilters 87 88 if tableDef.Partition != nil { 89 partTableIds := make([]uint64, tableDef.Partition.PartitionNum) 90 partTableNames := make([]string, tableDef.Partition.PartitionNum) 91 for j, partition := range tableDef.Partition.Partitions { 92 _, partTableDef := ctx.Resolve(tblInfo.objRef[i].SchemaName, partition.PartitionTableName, Snapshot{TS: ×tamp.Timestamp{}}) 93 partTableIds[j] = partTableDef.TblId 94 partTableNames[j] = partition.PartitionTableName 95 } 96 delPlanCtx.partitionInfos[tableDef.TblId] = &partSubTableInfo{ 97 partTableIDs: partTableIds, 98 partTableNames: partTableNames, 99 } 100 } 101 102 lastNodeId = appendSinkScanNode(builder, deleteBindCtx, sourceStep) 103 lastNodeId, err = makePreUpdateDeletePlan(ctx, builder, deleteBindCtx, delPlanCtx, lastNodeId) 104 if err != nil { 105 return nil, err 106 } 107 lastNodeId = appendSinkNode(builder, deleteBindCtx, lastNodeId) 108 nextSourceStep := builder.appendStep(lastNodeId) 109 delPlanCtx.sourceStep = nextSourceStep 110 111 err = buildDeletePlans(ctx, builder, deleteBindCtx, delPlanCtx) 112 if err != nil { 113 return nil, err 114 } 115 beginIdx = beginIdx + len(tableDef.Cols) 116 putDmlPlanCtx(delPlanCtx) 117 } 118 119 reduceSinkSinkScanNodes(query) 120 ReCalcQueryStats(builder, query) 121 reCheckifNeedLockWholeTable(builder) 122 query.StmtType = plan.Query_DELETE 123 return &Plan{ 124 Plan: &plan.Plan_Query{ 125 Query: query, 126 }, 127 }, err 128 }