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