github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/common/print.go (about) 1 // Copyright 2021 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 common 16 17 import ( 18 "bytes" 19 "fmt" 20 "strconv" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/container/batch" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/container/vector" 26 "github.com/matrixorigin/matrixone/pkg/logutil" 27 "github.com/matrixorigin/matrixone/pkg/pb/api" 28 "go.uber.org/zap" 29 "go.uber.org/zap/zapcore" 30 ) 31 32 type PPLevel int8 33 34 const ( 35 PPL0 PPLevel = iota 36 PPL1 37 PPL2 38 PPL3 39 PPL4 40 ) 41 42 type ZonemapPrintKind int 43 44 const ( 45 ZonemapPrintKindNormal ZonemapPrintKind = iota 46 ZonemapPrintKindCompose 47 ZonemapPrintKindHex 48 ) 49 50 const DefaultMaxRowsToPrint = 3 51 52 func RepeatStr(str string, times int) string { 53 for i := 0; i < times; i++ { 54 str = fmt.Sprintf("%s\t", str) 55 } 56 return str 57 } 58 59 func DoIfFatalEnabled(fn func()) { 60 if logutil.GetSkip1Logger().Core().Enabled(zapcore.FatalLevel) { 61 fn() 62 } 63 } 64 func DoIfErrorEnabled(fn func()) { 65 if logutil.GetSkip1Logger().Core().Enabled(zapcore.ErrorLevel) { 66 fn() 67 } 68 } 69 func DoIfWarnEnabled(fn func()) { 70 if logutil.GetSkip1Logger().Core().Enabled(zapcore.WarnLevel) { 71 fn() 72 } 73 } 74 func DoIfInfoEnabled(fn func()) { 75 if logutil.GetSkip1Logger().Core().Enabled(zapcore.InfoLevel) { 76 fn() 77 } 78 } 79 func DoIfDebugEnabled(fn func()) { 80 if logutil.GetSkip1Logger().Core().Enabled(zapcore.DebugLevel) { 81 fn() 82 } 83 } 84 85 type opt struct { 86 doNotPrintBinary bool 87 specialRowid bool // just a uint64, blockid 88 } 89 90 type TypePrintOpt interface { 91 apply(*opt) 92 } 93 94 type WithDoNotPrintBin struct{} 95 96 func (w WithDoNotPrintBin) apply(o *opt) { o.doNotPrintBinary = true } 97 98 type WithSpecialRowid struct{} 99 100 func (w WithSpecialRowid) apply(o *opt) { o.specialRowid = true } 101 102 func TypeStringValue(t types.Type, v any, isNull bool, opts ...TypePrintOpt) string { 103 if isNull { 104 return "null" 105 } 106 opt := &opt{} 107 for _, o := range opts { 108 o.apply(opt) 109 } 110 111 switch t.Oid { 112 case types.T_bool, types.T_int8, types.T_int16, types.T_int32, 113 types.T_int64, types.T_uint8, types.T_uint16, types.T_uint32, 114 types.T_uint64, types.T_float32, types.T_float64: 115 return fmt.Sprintf("%v", v) 116 case types.T_bit: 117 return fmt.Sprintf("%v", v) 118 case types.T_char, types.T_varchar, 119 types.T_binary, types.T_varbinary, types.T_text, types.T_blob: 120 buf := v.([]byte) 121 printable := true 122 for _, c := range buf { 123 if !strconv.IsPrint(rune(c)) { 124 printable = false 125 break 126 } 127 } 128 if printable { 129 if len(buf) > 500 { 130 buf = buf[:500] 131 } 132 return string(buf) 133 } else if opt.doNotPrintBinary { 134 return fmt.Sprintf("binary[%d]", len(buf)) 135 } else { 136 return fmt.Sprintf("%x", buf) 137 } 138 case types.T_array_float32: 139 // The parent function is mostly used to print the vector content for debugging. 140 return types.BytesToArrayToString[float32](v.([]byte)) 141 case types.T_array_float64: 142 return types.BytesToArrayToString[float64](v.([]byte)) 143 case types.T_date: 144 val := v.(types.Date) 145 return val.String() 146 case types.T_datetime: 147 val := v.(types.Datetime) 148 return val.String2(6) 149 case types.T_time: 150 val := v.(types.Time) 151 return val.String2(6) 152 case types.T_timestamp: 153 val := v.(types.Timestamp) 154 return val.String2(time.Local, 6) 155 case types.T_decimal64: 156 val := v.(types.Decimal64) 157 return val.Format(t.Scale) 158 case types.T_decimal128: 159 val := v.(types.Decimal128) 160 return val.Format(t.Scale) 161 case types.T_json: 162 val := v.([]byte) 163 j := types.DecodeJson(val) 164 return j.String() 165 case types.T_uuid: 166 val := v.(types.Uuid) 167 return val.ToString() 168 case types.T_TS: 169 val := v.(types.TS) 170 return val.ToString() 171 case types.T_Rowid: 172 val := v.(types.Rowid) 173 if opt.specialRowid { 174 return strconv.FormatUint(types.DecodeUint64(val[:]), 10) 175 } else { 176 val := v.(types.Rowid) 177 return val.String() 178 } 179 case types.T_Blockid: 180 val := v.(types.Blockid) 181 return val.String() 182 case types.T_enum: 183 val := v.(types.Enum) 184 return fmt.Sprintf("%v", val) 185 default: 186 return fmt.Sprintf("%v", v) 187 } 188 } 189 190 func vec2Str[T any](vec []T, v *vector.Vector, opts ...TypePrintOpt) string { 191 var w bytes.Buffer 192 _, _ = w.WriteString(fmt.Sprintf("[%d]: ", v.Length())) 193 first := true 194 for i := 0; i < len(vec); i++ { 195 if !first { 196 _ = w.WriteByte(',') 197 } 198 if v.GetNulls().Contains(uint64(i)) { 199 _, _ = w.WriteString(TypeStringValue(*v.GetType(), nil, true)) 200 } else { 201 _, _ = w.WriteString(TypeStringValue(*v.GetType(), vec[i], false, opts...)) 202 } 203 first = false 204 } 205 return w.String() 206 } 207 208 func MoVectorToString(v *vector.Vector, printN int, opts ...TypePrintOpt) string { 209 switch v.GetType().Oid { 210 case types.T_bool: 211 return vec2Str(vector.MustFixedCol[bool](v)[:printN], v) 212 case types.T_int8: 213 return vec2Str(vector.MustFixedCol[int8](v)[:printN], v) 214 case types.T_int16: 215 return vec2Str(vector.MustFixedCol[int16](v)[:printN], v) 216 case types.T_int32: 217 return vec2Str(vector.MustFixedCol[int32](v)[:printN], v) 218 case types.T_int64: 219 return vec2Str(vector.MustFixedCol[int64](v)[:printN], v) 220 case types.T_uint8: 221 return vec2Str(vector.MustFixedCol[uint8](v)[:printN], v) 222 case types.T_uint16: 223 return vec2Str(vector.MustFixedCol[uint16](v)[:printN], v) 224 case types.T_uint32: 225 return vec2Str(vector.MustFixedCol[uint32](v)[:printN], v) 226 case types.T_uint64: 227 return vec2Str(vector.MustFixedCol[uint64](v)[:printN], v) 228 case types.T_float32: 229 return vec2Str(vector.MustFixedCol[float32](v)[:printN], v) 230 case types.T_float64: 231 return vec2Str(vector.MustFixedCol[float64](v)[:printN], v) 232 case types.T_date: 233 return vec2Str(vector.MustFixedCol[types.Date](v)[:printN], v) 234 case types.T_datetime: 235 return vec2Str(vector.MustFixedCol[types.Datetime](v)[:printN], v) 236 case types.T_time: 237 return vec2Str(vector.MustFixedCol[types.Time](v)[:printN], v) 238 case types.T_timestamp: 239 return vec2Str(vector.MustFixedCol[types.Timestamp](v)[:printN], v) 240 case types.T_enum: 241 return vec2Str(vector.MustFixedCol[types.Enum](v)[:printN], v) 242 case types.T_decimal64: 243 return vec2Str(vector.MustFixedCol[types.Decimal64](v)[:printN], v) 244 case types.T_decimal128: 245 return vec2Str(vector.MustFixedCol[types.Decimal128](v)[:printN], v) 246 case types.T_uuid: 247 return vec2Str(vector.MustFixedCol[types.Uuid](v)[:printN], v) 248 case types.T_TS: 249 return vec2Str(vector.MustFixedCol[types.TS](v)[:printN], v) 250 case types.T_Rowid: 251 return vec2Str(vector.MustFixedCol[types.Rowid](v)[:printN], v) 252 case types.T_Blockid: 253 return vec2Str(vector.MustFixedCol[types.Blockid](v)[:printN], v) 254 } 255 if v.GetType().IsVarlen() { 256 return vec2Str(vector.MustBytesCol(v)[:printN], v, opts...) 257 } 258 return fmt.Sprintf("unkown type vec... %v", *v.GetType()) 259 } 260 261 func MoBatchToString(moBat *batch.Batch, printN int) string { 262 n := moBat.RowCount() 263 if n > printN { 264 n = printN 265 } 266 buf := new(bytes.Buffer) 267 for i, vec := range moBat.Vecs { 268 if len(moBat.Attrs) == 0 { 269 fmt.Fprintf(buf, "[col%v] = %v\n", i, MoVectorToString(vec, n)) 270 } else { 271 fmt.Fprintf(buf, "[%v] = %v\n", moBat.Attrs[i], MoVectorToString(vec, n, WithDoNotPrintBin{})) 272 } 273 } 274 return buf.String() 275 } 276 277 func ApiBatchToString(apiBat *api.Batch, printN int) string { 278 if apiBat == nil { 279 return "" 280 } 281 bat, _ := batch.ProtoBatchToBatch(apiBat) 282 return MoBatchToString(bat, printN) 283 } 284 285 func DebugMoBatch(moBat *batch.Batch) string { 286 if !logutil.GetSkip1Logger().Core().Enabled(zap.DebugLevel) { 287 return "not debug level" 288 } 289 return MoBatchToString(moBat, DefaultMaxRowsToPrint) 290 }