github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/explain/explain_expr.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 explain 16 17 import ( 18 "bytes" 19 "context" 20 "fmt" 21 "strconv" 22 "strings" 23 24 "github.com/matrixorigin/matrixone/pkg/common/moerr" 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/plan/function" 29 "github.com/matrixorigin/matrixone/pkg/vm/process" 30 ) 31 32 func describeMessage(m *plan.MsgHeader, buf *bytes.Buffer) { 33 buf.WriteString("[tag ") 34 fmt.Fprintf(buf, "%d", m.MsgTag) 35 buf.WriteString(" , type ") 36 msgType := process.MsgType(m.MsgType) 37 buf.WriteString(msgType.MessageName()) 38 buf.WriteString("]") 39 } 40 41 func describeExpr(ctx context.Context, expr *plan.Expr, options *ExplainOptions, buf *bytes.Buffer) error { 42 switch exprImpl := expr.Expr.(type) { 43 case *plan.Expr_Col: 44 if len(exprImpl.Col.Name) > 0 { 45 buf.WriteString(exprImpl.Col.Name) 46 } else { 47 buf.WriteString("#[") 48 buf.WriteString(strconv.Itoa(int(exprImpl.Col.RelPos))) 49 buf.WriteString(",") 50 buf.WriteString(strconv.Itoa(int(exprImpl.Col.ColPos))) 51 buf.WriteString("]") 52 } 53 54 case *plan.Expr_Lit: 55 if exprImpl.Lit.Isnull { 56 buf.WriteString("(null)") 57 break 58 } 59 60 switch val := exprImpl.Lit.Value.(type) { 61 case *plan.Literal_I8Val: 62 fmt.Fprintf(buf, "%d", val.I8Val) 63 case *plan.Literal_I16Val: 64 fmt.Fprintf(buf, "%d", val.I16Val) 65 case *plan.Literal_I32Val: 66 fmt.Fprintf(buf, "%d", val.I32Val) 67 case *plan.Literal_I64Val: 68 fmt.Fprintf(buf, "%d", val.I64Val) 69 case *plan.Literal_U8Val: 70 fmt.Fprintf(buf, "%d", val.U8Val) 71 case *plan.Literal_U16Val: 72 fmt.Fprintf(buf, "%d", val.U16Val) 73 case *plan.Literal_U32Val: 74 fmt.Fprintf(buf, "%d", val.U32Val) 75 case *plan.Literal_U64Val: 76 fmt.Fprintf(buf, "%d", val.U64Val) 77 case *plan.Literal_Fval: 78 fmt.Fprintf(buf, "%v", strconv.FormatFloat(float64(val.Fval), 'f', -1, 32)) 79 case *plan.Literal_Dval: 80 fmt.Fprintf(buf, "%v", strconv.FormatFloat(val.Dval, 'f', -1, 64)) 81 case *plan.Literal_Dateval: 82 fmt.Fprintf(buf, "%s", types.Date(val.Dateval)) 83 case *plan.Literal_Datetimeval: 84 fmt.Fprintf(buf, "%s", types.Datetime(val.Datetimeval).String2(expr.Typ.Scale)) 85 case *plan.Literal_Timeval: 86 fmt.Fprintf(buf, "%s", types.Time(val.Timeval).String2(expr.Typ.Scale)) 87 case *plan.Literal_Sval: 88 buf.WriteString("'" + val.Sval + "'") 89 case *plan.Literal_Bval: 90 fmt.Fprintf(buf, "%v", val.Bval) 91 case *plan.Literal_EnumVal: 92 fmt.Fprintf(buf, "%v", val.EnumVal) 93 case *plan.Literal_Decimal64Val: 94 fmt.Fprintf(buf, "%s", types.Decimal64(val.Decimal64Val.A).Format(expr.Typ.GetScale())) 95 case *plan.Literal_Decimal128Val: 96 fmt.Fprintf(buf, "%s", 97 types.Decimal128{B0_63: uint64(val.Decimal128Val.A), B64_127: uint64(val.Decimal128Val.B)}.Format(expr.Typ.GetScale())) 98 } 99 100 case *plan.Expr_F: 101 err := funcExprExplain(ctx, expr.GetF(), &expr.Typ, options, buf) 102 if err != nil { 103 return err 104 } 105 case *plan.Expr_W: 106 w := exprImpl.W 107 err := funcExprExplain(ctx, w.WindowFunc.GetF(), &expr.Typ, options, buf) 108 if err != nil { 109 return err 110 } 111 112 if len(w.PartitionBy) > 0 { 113 buf.WriteString("; Partition By: ") 114 for i, arg := range w.PartitionBy { 115 if i > 0 { 116 buf.WriteString(", ") 117 } 118 err = describeExpr(ctx, arg, options, buf) 119 if err != nil { 120 return err 121 } 122 } 123 } 124 125 if len(w.OrderBy) > 0 { 126 buf.WriteString("; Order By: ") 127 for i, arg := range w.OrderBy { 128 if i > 0 { 129 buf.WriteString(", ") 130 } 131 err = describeExpr(ctx, arg.Expr, options, buf) 132 if err != nil { 133 return err 134 } 135 } 136 } 137 case *plan.Expr_Sub: 138 subqryExpr := expr.Expr.(*plan.Expr_Sub) 139 buf.WriteString("subquery nodeId = " + strconv.FormatInt(int64(subqryExpr.Sub.NodeId), 10)) 140 case *plan.Expr_Corr: 141 buf.WriteString("#[") 142 buf.WriteString(strconv.FormatInt(int64(exprImpl.Corr.RelPos), 10)) 143 buf.WriteString(",") 144 buf.WriteString(strconv.FormatInt(int64(exprImpl.Corr.ColPos), 10)) 145 buf.WriteString(":") 146 buf.WriteString(strconv.FormatInt(int64(exprImpl.Corr.Depth), 10)) 147 buf.WriteString("]") 148 case *plan.Expr_V: 149 if exprImpl.V.System { 150 if exprImpl.V.Global { 151 buf.WriteString("@@global." + exprImpl.V.Name) 152 } else { 153 buf.WriteString("@@session." + exprImpl.V.Name) 154 } 155 } else { 156 buf.WriteString("@" + exprImpl.V.Name) 157 } 158 case *plan.Expr_P: 159 buf.WriteString("?") 160 case *plan.Expr_List: 161 exprlist := expr.Expr.(*plan.Expr_List) 162 if exprlist.List.List != nil { 163 exprListDescImpl := NewExprListDescribeImpl(exprlist.List.List) 164 err := exprListDescImpl.GetDescription(ctx, options, buf) 165 if err != nil { 166 return err 167 } 168 } 169 case *plan.Expr_Vec: 170 vec := vector.NewVec(types.T_any.ToType()) 171 vec.UnmarshalBinary(exprImpl.Vec.Data) 172 if vec.Length() > 16 { 173 //don't display too long data in explain 174 originalLen := vec.Length() 175 vec.SetLength(16) 176 buf.WriteString(vec.String()) 177 s := fmt.Sprintf("... %v values", originalLen) 178 buf.WriteString(s) 179 } else { 180 buf.WriteString(vec.String()) 181 } 182 vec.Free(nil) 183 case *plan.Expr_T: 184 tt := types.T(expr.Typ.Id) 185 if tt == types.T_decimal64 || tt == types.T_decimal128 { 186 fmt.Fprintf(buf, "%s(%d, %d))", tt.String(), expr.Typ.Width, expr.Typ.Scale) 187 } else { 188 fmt.Fprintf(buf, "%s)", tt.String()) 189 } 190 default: 191 panic("unsupported expr") 192 } 193 return nil 194 } 195 196 // generator function expression(Expr_F) explain information 197 func funcExprExplain(ctx context.Context, funcExpr *plan.Function, Typ *plan.Type, options *ExplainOptions, buf *bytes.Buffer) error { 198 // SysFunsAndOperatorsMap 199 funcName := funcExpr.GetFunc().GetObjName() 200 funcDef := funcExpr.GetFunc() 201 202 layout, err := function.GetLayoutById(ctx, funcDef.Obj&function.DistinctMask) 203 if err != nil { 204 return moerr.NewInvalidInput(ctx, "invalid function or opreator '%s'", funcName) 205 } 206 207 switch layout { 208 case function.STANDARD_FUNCTION: 209 buf.WriteString(funcExpr.Func.GetObjName() + "(") 210 if len(funcExpr.Args) > 0 { 211 var first = true 212 for _, v := range funcExpr.Args { 213 if !first { 214 buf.WriteString(", ") 215 } 216 first = false 217 err = describeExpr(ctx, v, options, buf) 218 if err != nil { 219 return err 220 } 221 } 222 } 223 buf.WriteString(")") 224 case function.UNARY_ARITHMETIC_OPERATOR: 225 var opertator string 226 if funcExpr.Func.GetObjName() == "UNARY_PLUS" { 227 opertator = "+" 228 } else { 229 opertator = "-" 230 } 231 buf.WriteString("(" + opertator) 232 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 233 if err != nil { 234 return err 235 } 236 buf.WriteString(")") 237 case function.UNARY_LOGICAL_OPERATOR: 238 buf.WriteString("(" + funcExpr.Func.GetObjName() + " ") 239 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 240 if err != nil { 241 return err 242 } 243 buf.WriteString(")") 244 //result += "(" + funcExpr.Func.GetObjName() + " " + describeExpr + ")" 245 case function.BINARY_ARITHMETIC_OPERATOR: 246 fallthrough 247 case function.BINARY_LOGICAL_OPERATOR: 248 fallthrough 249 case function.COMPARISON_OPERATOR: 250 buf.WriteString("(") 251 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 252 if err != nil { 253 return err 254 } 255 buf.WriteString(" " + funcExpr.Func.GetObjName() + " ") 256 err = describeExpr(ctx, funcExpr.Args[1], options, buf) 257 if err != nil { 258 return err 259 } 260 buf.WriteString(")") 261 case function.CAST_EXPRESSION: 262 buf.WriteString(funcName) 263 buf.WriteString("(") 264 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 265 if err != nil { 266 return err 267 } 268 tt := types.T(Typ.Id) 269 if tt == types.T_decimal64 || tt == types.T_decimal128 { 270 fmt.Fprintf(buf, " AS %s(%d, %d))", tt.String(), Typ.Width, Typ.Scale) 271 } else { 272 fmt.Fprintf(buf, " AS %s)", tt.String()) 273 } 274 case function.CASE_WHEN_EXPRESSION: 275 // TODO need rewrite to deal with case is nil 276 buf.WriteString("CASE") 277 // case when expression has two part(case when condition and else exression) 278 condSize := len(funcExpr.Args) - 1 279 for i := 0; i < condSize; i += 2 { 280 whenExpr := funcExpr.Args[i] 281 thenExpr := funcExpr.Args[i+1] 282 buf.WriteString(" WHEN ") 283 err = describeExpr(ctx, whenExpr, options, buf) 284 if err != nil { 285 return err 286 } 287 buf.WriteString(" THEN ") 288 err = describeExpr(ctx, thenExpr, options, buf) 289 if err != nil { 290 return err 291 } 292 } 293 294 if len(funcExpr.Args)%2 == 1 { 295 lastIndex := len(funcExpr.Args) - 1 296 elseExpr := funcExpr.Args[lastIndex] 297 // get else expression 298 buf.WriteString(" ELSE ") 299 err = describeExpr(ctx, elseExpr, options, buf) 300 if err != nil { 301 return err 302 } 303 } 304 buf.WriteString(" END") 305 case function.BETWEEN_AND_EXPRESSION: 306 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 307 if err != nil { 308 return err 309 } 310 buf.WriteString(" BETWEEN ") 311 err = describeExpr(ctx, funcExpr.Args[1], options, buf) 312 if err != nil { 313 return err 314 } 315 buf.WriteString(" AND ") 316 err = describeExpr(ctx, funcExpr.Args[2], options, buf) 317 if err != nil { 318 return err 319 } 320 case function.IN_PREDICATE: 321 if len(funcExpr.Args) != 2 { 322 panic("Nested query predicate,such as in,exist,all,any parameter number error!") 323 } 324 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 325 if err != nil { 326 return err 327 } 328 buf.WriteString(" " + funcExpr.Func.GetObjName() + " (") 329 err = describeExpr(ctx, funcExpr.Args[1], options, buf) 330 if err != nil { 331 return err 332 } 333 buf.WriteString(")") 334 case function.EXISTS_ANY_PREDICATE: 335 buf.WriteString(funcExpr.Func.GetObjName() + "(") 336 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 337 if err != nil { 338 return err 339 } 340 buf.WriteString(")") 341 case function.IS_EXPRESSION: 342 buf.WriteString("(") 343 err := describeExpr(ctx, funcExpr.Args[0], options, buf) 344 if err != nil { 345 return err 346 } 347 buf.WriteString(fmt.Sprintf(" IS %s)", strings.ToUpper(funcExpr.Func.GetObjName()[2:]))) 348 case function.IS_NOT_EXPRESSION: 349 buf.WriteString("(") 350 err := describeExpr(ctx, funcExpr.Args[0], options, buf) 351 if err != nil { 352 return err 353 } 354 buf.WriteString(fmt.Sprintf(" IS NOT %s)", strings.ToUpper(funcExpr.Func.GetObjName()[5:]))) 355 case function.NOPARAMETER_FUNCTION: 356 buf.WriteString(funcExpr.Func.GetObjName()) 357 case function.DATE_INTERVAL_EXPRESSION: 358 buf.WriteString(funcExpr.Func.GetObjName() + " ") 359 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 360 if err != nil { 361 return err 362 } 363 case function.EXTRACT_FUNCTION: 364 buf.WriteString(funcExpr.Func.GetObjName() + "(") 365 err = describeExpr(ctx, funcExpr.Args[0], options, buf) 366 if err != nil { 367 return err 368 } 369 buf.WriteString(" from ") 370 err = describeExpr(ctx, funcExpr.Args[1], options, buf) 371 if err != nil { 372 return err 373 } 374 buf.WriteString(")") 375 case function.UNKNOW_KIND_FUNCTION: 376 return moerr.NewInvalidInput(ctx, "explain contains UNKNOW_KIND_FUNCTION") 377 } 378 return nil 379 }