github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/build_insert.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 "github.com/matrixorigin/matrixone/pkg/common/moerr" 19 "github.com/matrixorigin/matrixone/pkg/pb/plan" 20 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 21 ) 22 23 func buildInsert(stmt *tree.Insert, ctx CompilerContext, isReplace bool) (p *Plan, err error) { 24 if len(stmt.OnDuplicateUpdate) > 0 { 25 return nil, moerr.NewNotSupported(ctx.GetContext(), "INSERT ... ON DUPLICATE KEY UPDATE ...") 26 } 27 if isReplace { 28 return nil, moerr.NewNotSupported(ctx.GetContext(), "Not support replace statement") 29 } 30 31 tblInfo, err := getDmlTableInfo(ctx, tree.TableExprs{stmt.Table}, nil, nil) 32 if err != nil { 33 return nil, err 34 } 35 rewriteInfo := &dmlSelectInfo{ 36 typ: "insert", 37 rootId: -1, 38 tblInfo: tblInfo, 39 } 40 tblDef := tblInfo.tableDefs[0] 41 clusterTable, err := getAccountInfoOfClusterTable(ctx, stmt.Accounts, tblDef, tblInfo.isClusterTable[0]) 42 if err != nil { 43 return nil, err 44 } 45 46 builder := NewQueryBuilder(plan.Query_SELECT, ctx) 47 bindCtx := NewBindContext(builder, nil) 48 bindCtx.groupTag = builder.genNewTag() 49 bindCtx.aggregateTag = builder.genNewTag() 50 bindCtx.projectTag = builder.genNewTag() 51 52 err = initInsertStmt(builder, bindCtx, stmt, rewriteInfo) 53 if err != nil { 54 return nil, err 55 } 56 57 if tblInfo.haveConstraint { 58 for i, tableDef := range tblInfo.tableDefs { 59 err = rewriteDmlSelectInfo(builder, bindCtx, rewriteInfo, tableDef, rewriteInfo.derivedTableId, i) 60 if err != nil { 61 return nil, err 62 } 63 } 64 } 65 66 // append ProjectNode 67 rewriteInfo.rootId = builder.appendNode(&plan.Node{ 68 NodeType: plan.Node_PROJECT, 69 ProjectList: rewriteInfo.projectList, 70 Children: []int32{rewriteInfo.rootId}, 71 BindingTags: []int32{bindCtx.projectTag}, 72 }, bindCtx) 73 74 bindCtx.results = rewriteInfo.projectList 75 builder.qry.Steps = append(builder.qry.Steps, rewriteInfo.rootId) 76 query, err := builder.createQuery() 77 if err != nil { 78 return nil, err 79 } 80 81 // append insert node 82 insertCtx := &plan.InsertCtx{ 83 Ref: rewriteInfo.tblInfo.objRef[0], 84 TableDef: rewriteInfo.tblInfo.tableDefs[0], 85 Idx: make([]int32, len(rewriteInfo.tblInfo.tableDefs[0].Cols)), 86 87 ClusterTable: clusterTable, 88 } 89 for j := range tblDef.Cols { 90 insertCtx.Idx[j] = int32(j) 91 } 92 if len(rewriteInfo.parentIdx) == 1 { 93 insertCtx.ParentIdx = rewriteInfo.parentIdx[0] 94 } 95 96 node := &Node{ 97 NodeType: plan.Node_INSERT, 98 ObjRef: insertCtx.Ref, 99 TableDef: insertCtx.TableDef, 100 Children: []int32{query.Steps[len(query.Steps)-1]}, 101 NodeId: int32(len(query.Nodes)), 102 InsertCtx: insertCtx, 103 } 104 query.Nodes = append(query.Nodes, node) 105 query.Steps[len(query.Steps)-1] = node.NodeId 106 query.StmtType = plan.Query_INSERT 107 108 return &Plan{ 109 Plan: &plan.Plan_Query{ 110 Query: query, 111 }, 112 }, err 113 }