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  }