github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/result_scan.go (about) 1 // Copyright 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 "encoding/json" 19 20 "github.com/matrixorigin/matrixone/pkg/catalog" 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/container/batch" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/container/vector" 25 "github.com/matrixorigin/matrixone/pkg/pb/plan" 26 "github.com/matrixorigin/matrixone/pkg/sql/colexec" 27 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 28 ) 29 30 func (builder *QueryBuilder) buildResultScan(tbl *tree.TableFunction, ctx *BindContext) (int32, error) { 31 var err error 32 val, err := builder.compCtx.ResolveVariable("save_query_result", true, true) 33 if err == nil { 34 if v, _ := val.(int8); v == 0 { 35 return 0, moerr.NewNoConfig(builder.GetContext(), "save query result") 36 } 37 } 38 ctx.binder = NewTableBinder(builder, ctx) 39 exprs := make([]*plan.Expr, 0, len(tbl.Func.Exprs)) 40 for _, v := range tbl.Func.Exprs { 41 curExpr, err := ctx.binder.BindExpr(v, 0, false) 42 if err != nil { 43 return 0, err 44 } 45 exprs = append(exprs, curExpr) 46 } 47 exprs[0], err = appendCastBeforeExpr(builder.GetContext(), exprs[0], &plan.Type{ 48 Id: int32(types.T_uuid), 49 NotNullable: true, 50 }) 51 if err != nil { 52 return 0, err 53 } 54 // calculate uuid 55 bat := batch.NewWithSize(0) 56 bat.Zs = []int64{1} 57 vec, err := colexec.EvalExpr(bat, builder.compCtx.GetProcess(), exprs[0]) 58 if err != nil { 59 return 0, err 60 } 61 uuid := vector.MustTCols[types.Uuid](vec)[0] 62 // get cols 63 cols, path, err := builder.compCtx.GetQueryResultMeta(uuid.ToString()) 64 if err != nil { 65 return 0, err 66 } 67 if len(path) == 0 { 68 return 0, moerr.NewInvalidInput(builder.GetContext(), "empty %s", "query result") 69 } 70 typs := make([]types.Type, len(cols)) 71 for i, c := range cols { 72 typs[i] = types.New(types.T(c.Typ.Id), c.Typ.Width, c.Typ.Scale, c.Typ.Precision) 73 } 74 builder.compCtx.GetProcess().SessionInfo.ResultColTypes = typs 75 name2ColIndex := map[string]int32{} 76 for i := 0; i < len(cols); i++ { 77 name2ColIndex[cols[i].Name] = int32(i) 78 } 79 tableDef := &plan.TableDef{ 80 Name: uuid.ToString(), 81 TableType: "query_result", 82 Cols: cols, 83 Name2ColIndex: name2ColIndex, 84 } 85 // build external param 86 p := &tree.ExternParam{ 87 ExParamConst: tree.ExParamConst{ 88 // ScanType: tree.S3, 89 Filepath: path, 90 // FileService: builder.compCtx.GetProcess().FileService, 91 // S3Param: &tree.S3Parameter{}, 92 Tail: &tree.TailParameter{}, 93 }, 94 ExParam: tree.ExParam{ 95 QueryResult: true, 96 }, 97 } 98 b, err := json.Marshal(p) 99 if err != nil { 100 return 0, err 101 } 102 properties := []*plan.Property{ 103 { 104 Key: catalog.SystemRelAttr_Kind, 105 Value: catalog.SystemExternalRel, 106 }, 107 { 108 Key: catalog.SystemRelAttr_CreateSQL, 109 Value: string(b), 110 }, 111 } 112 tableDef.Defs = append(tableDef.Defs, &plan.TableDef_DefType{ 113 Def: &plan.TableDef_DefType_Properties{ 114 Properties: &plan.PropertiesDef{ 115 Properties: properties, 116 }, 117 }}) 118 tableDef.Createsql = string(b) 119 node := &plan.Node{ 120 NodeType: plan.Node_EXTERNAL_SCAN, 121 Stats: &plan.Stats{}, 122 TableDef: tableDef, 123 BindingTags: []int32{builder.genNewTag()}, 124 NotCacheable: true, 125 } 126 nodeID := builder.appendNode(node, ctx) 127 return nodeID, nil 128 }