github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/ctl/table_stat.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 ctl 16 17 import ( 18 "strconv" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/container/bytejson" 22 "github.com/matrixorigin/matrixone/pkg/container/nulls" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/container/vector" 25 "github.com/matrixorigin/matrixone/pkg/defines" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine" 27 "github.com/matrixorigin/matrixone/pkg/vm/process" 28 ) 29 30 // MoTableRows returns an estimated row number of a table. 31 func MoTableRows(vecs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 32 vec := vector.New(types.New(types.T_int64, 0, 0, 0)) 33 count := vecs[0].Length() 34 dbs := vector.MustStrCols(vecs[0]) 35 tbls := vector.MustStrCols(vecs[1]) 36 e := proc.Ctx.Value(defines.EngineKey{}).(engine.Engine) 37 txn, err := proc.TxnClient.New() 38 if err != nil { 39 return nil, err 40 } 41 defer txn.Rollback(proc.Ctx) 42 if err := e.New(proc.Ctx, txn); err != nil { 43 return nil, err 44 } 45 defer e.Rollback(proc.Ctx, txn) 46 for i := 0; i < count; i++ { 47 db, err := e.Database(proc.Ctx, dbs[i], txn) 48 if err != nil { 49 return nil, err 50 } 51 rel, err := db.Relation(proc.Ctx, tbls[i]) 52 if err != nil { 53 return nil, err 54 } 55 rel.Ranges(proc.Ctx, nil) 56 rows, err := rel.Rows(proc.Ctx) 57 if err != nil { 58 return nil, err 59 } 60 if err := vec.Append(rows, false, proc.Mp()); err != nil { 61 vec.Free(proc.Mp()) 62 return nil, err 63 } 64 } 65 return vec, nil 66 } 67 68 // MoTableSize returns an estimated size of a table. 69 func MoTableSize(vecs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 70 vec := vector.New(types.New(types.T_int64, 0, 0, 0)) 71 count := vecs[0].Length() 72 dbs := vector.MustStrCols(vecs[0]) 73 tbls := vector.MustStrCols(vecs[1]) 74 e := proc.Ctx.Value(defines.EngineKey{}).(engine.Engine) 75 txn, err := proc.TxnClient.New() 76 if err != nil { 77 return nil, err 78 } 79 defer txn.Rollback(proc.Ctx) 80 if err := e.New(proc.Ctx, txn); err != nil { 81 return nil, err 82 } 83 defer e.Rollback(proc.Ctx, txn) 84 for i := 0; i < count; i++ { 85 db, err := e.Database(proc.Ctx, dbs[i], txn) 86 if err != nil { 87 return nil, err 88 } 89 rel, err := db.Relation(proc.Ctx, tbls[i]) 90 if err != nil { 91 return nil, err 92 } 93 rel.Ranges(proc.Ctx, nil) 94 rows, err := rel.Rows(proc.Ctx) 95 if err != nil { 96 return nil, err 97 } 98 attrs, err := rel.TableColumns(proc.Ctx) 99 if err != nil { 100 return nil, err 101 } 102 size := int64(0) 103 for _, attr := range attrs { 104 size += rows * int64(attr.Type.TypeSize()) 105 } 106 if err := vec.Append(size, false, proc.Mp()); err != nil { 107 vec.Free(proc.Mp()) 108 return nil, err 109 } 110 } 111 return vec, nil 112 113 } 114 115 // MoTableColMax return the max value of the column 116 func MoTableColMax(vecs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 117 count := vecs[0].Length() 118 dbs := vector.MustStrCols(vecs[0]) 119 tbls := vector.MustStrCols(vecs[1]) 120 cols := vector.MustStrCols(vecs[2]) 121 122 returnType := types.T_varchar.ToType() 123 var resultVec *vector.Vector = nil 124 resultValues := make([]string, count) 125 resultNsp := nulls.NewWithSize(count) 126 127 if vecs[0].IsScalarNull() || vecs[1].IsScalarNull() || vecs[2].IsScalarNull() { 128 return proc.AllocScalarNullVector(returnType), nil 129 } 130 131 // set null row 132 nulls.Or(vecs[0].Nsp, vecs[1].Nsp, resultNsp) 133 nulls.Or(vecs[2].Nsp, resultNsp, resultNsp) 134 135 e := proc.Ctx.Value(defines.EngineKey{}).(engine.Engine) 136 txn, err := proc.TxnClient.New() 137 if err != nil { 138 return nil, err 139 } 140 defer txn.Rollback(proc.Ctx) 141 if err := e.New(proc.Ctx, txn); err != nil { 142 return nil, err 143 } 144 defer e.Rollback(proc.Ctx, txn) 145 146 for i := 0; i < count; i++ { 147 col := cols[i] 148 if col == "__mo_rowid" { 149 return nil, moerr.NewInvalidArg(proc.Ctx, "mo_table_col_max has bad input column", col) 150 } 151 if tbls[i] == "mo_database" || tbls[i] == "mo_tables" || tbls[i] == "mo_columns" || tbls[i] == "sys_async_task" { 152 return nil, moerr.NewInvalidArg(proc.Ctx, "mo_table_col_max has bad input table", tbls[i]) 153 } 154 155 db, err := e.Database(proc.Ctx, dbs[i], txn) 156 if err != nil { 157 return nil, err 158 } 159 rel, err := db.Relation(proc.Ctx, tbls[i]) 160 if err != nil { 161 return nil, err 162 } 163 rel.Ranges(proc.Ctx, nil) 164 165 tableColumns, err := rel.TableColumns(proc.Ctx) 166 if err != nil { 167 return nil, err 168 } 169 170 //Get table max and min value from zonemap 171 tableVal, _, err := rel.MaxAndMinValues(proc.Ctx) 172 if err != nil { 173 return nil, err 174 } 175 176 for j := 0; j < len(tableColumns); j++ { 177 if tableColumns[j].Name == col { 178 resultValues[i] = getVlaueInStr(tableVal[j][1]) 179 break 180 } 181 } 182 } 183 resultVec = vector.NewWithStrings(types.T_varchar.ToType(), resultValues, resultNsp, proc.Mp()) 184 return resultVec, nil 185 } 186 187 // MoTableColMax return the max value of the column 188 func MoTableColMin(vecs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 189 count := vecs[0].Length() 190 dbs := vector.MustStrCols(vecs[0]) 191 tbls := vector.MustStrCols(vecs[1]) 192 cols := vector.MustStrCols(vecs[2]) 193 194 returnType := types.T_varchar.ToType() 195 var resultVec *vector.Vector = nil 196 resultValues := make([]string, count) 197 resultNsp := nulls.NewWithSize(count) 198 199 if vecs[0].IsScalarNull() || vecs[1].IsScalarNull() || vecs[2].IsScalarNull() { 200 return proc.AllocScalarNullVector(returnType), nil 201 } 202 203 // set null row 204 nulls.Or(vecs[0].Nsp, vecs[1].Nsp, resultNsp) 205 nulls.Or(vecs[2].Nsp, resultNsp, resultNsp) 206 207 e := proc.Ctx.Value(defines.EngineKey{}).(engine.Engine) 208 txn, err := proc.TxnClient.New() 209 if err != nil { 210 return nil, err 211 } 212 defer txn.Rollback(proc.Ctx) 213 if err := e.New(proc.Ctx, txn); err != nil { 214 return nil, err 215 } 216 defer e.Rollback(proc.Ctx, txn) 217 218 for i := 0; i < count; i++ { 219 col := cols[i] 220 if col == "__mo_rowid" { 221 return nil, moerr.NewInvalidArg(proc.Ctx, "mo_table_col_min has bad input column", col) 222 } 223 if tbls[i] == "mo_database" || tbls[i] == "mo_tables" || tbls[i] == "mo_columns" || tbls[i] == "sys_async_task" { 224 return nil, moerr.NewInvalidArg(proc.Ctx, "mo_table_col_min has bad input table:", tbls[i]) 225 } 226 227 db, err := e.Database(proc.Ctx, dbs[i], txn) 228 if err != nil { 229 return nil, err 230 } 231 rel, err := db.Relation(proc.Ctx, tbls[i]) 232 if err != nil { 233 return nil, err 234 } 235 rel.Ranges(proc.Ctx, nil) 236 237 tableColumns, err := rel.TableColumns(proc.Ctx) 238 if err != nil { 239 return nil, err 240 } 241 242 //Get table max and min value from zonemap 243 tableVal, _, err := rel.MaxAndMinValues(proc.Ctx) 244 if err != nil { 245 return nil, err 246 } 247 248 for j := 0; j < len(tableColumns); j++ { 249 if tableColumns[j].Name == col { 250 resultValues[i] = getVlaueInStr(tableVal[j][0]) 251 break 252 } 253 } 254 } 255 resultVec = vector.NewWithStrings(types.T_varchar.ToType(), resultValues, resultNsp, proc.Mp()) 256 return resultVec, nil 257 } 258 259 func getVlaueInStr(value any) string { 260 switch v := value.(type) { 261 case bool: 262 if v { 263 return "true" 264 } else { 265 return "false" 266 } 267 case uint8: 268 return strconv.FormatUint(uint64(v), 10) 269 case uint16: 270 return strconv.FormatUint(uint64(v), 10) 271 case uint32: 272 return strconv.FormatUint(uint64(v), 10) 273 case uint64: 274 return strconv.FormatUint(uint64(v), 10) 275 case int8: 276 return strconv.FormatInt(int64(v), 10) 277 case int16: 278 return strconv.FormatInt(int64(v), 10) 279 case int32: 280 return strconv.FormatInt(int64(v), 10) 281 case int64: 282 return strconv.FormatInt(int64(v), 10) 283 case float32: 284 return strconv.FormatFloat(float64(v), 'f', -1, 32) 285 case float64: 286 return strconv.FormatFloat(v, 'f', -1, 32) 287 case string: 288 return v 289 case []byte: 290 return string(v) 291 case int: 292 return strconv.FormatInt(int64(v), 10) 293 case uint: 294 return strconv.FormatUint(uint64(v), 10) 295 case types.Date: 296 return v.String() 297 case types.Time: 298 return v.String() 299 case types.Datetime: 300 return v.String() 301 case types.Timestamp: 302 return v.String() 303 case bytejson.ByteJson: 304 return v.String() 305 case types.Uuid: 306 return v.ToString() 307 case types.Decimal64: 308 return v.String() 309 case types.Decimal128: 310 return v.String() 311 default: 312 return "" 313 } 314 }