github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/column.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"fmt"
    18  	"sort"
    19  	"strings"
    20  
    21  	"github.com/whtcorpsinc/errors"
    22  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    23  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    24  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    25  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    26  	"github.com/whtcorpsinc/milevadb/types"
    27  	"github.com/whtcorpsinc/milevadb/types/json"
    28  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    29  	"github.com/whtcorpsinc/milevadb/soliton/codec"
    30  )
    31  
    32  // CorrelatedDeferredCauset stands for a defCausumn in a correlated sub query.
    33  type CorrelatedDeferredCauset struct {
    34  	DeferredCauset
    35  
    36  	Data *types.Causet
    37  }
    38  
    39  // Clone implements Expression interface.
    40  func (defCaus *CorrelatedDeferredCauset) Clone() Expression {
    41  	var d types.Causet
    42  	return &CorrelatedDeferredCauset{
    43  		DeferredCauset: defCaus.DeferredCauset,
    44  		Data:   &d,
    45  	}
    46  }
    47  
    48  // VecEvalInt evaluates this memex in a vectorized manner.
    49  func (defCaus *CorrelatedDeferredCauset) VecEvalInt(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    50  	return genVecFromConstExpr(ctx, defCaus, types.ETInt, input, result)
    51  }
    52  
    53  // VecEvalReal evaluates this memex in a vectorized manner.
    54  func (defCaus *CorrelatedDeferredCauset) VecEvalReal(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    55  	return genVecFromConstExpr(ctx, defCaus, types.ETReal, input, result)
    56  }
    57  
    58  // VecEvalString evaluates this memex in a vectorized manner.
    59  func (defCaus *CorrelatedDeferredCauset) VecEvalString(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    60  	return genVecFromConstExpr(ctx, defCaus, types.ETString, input, result)
    61  }
    62  
    63  // VecEvalDecimal evaluates this memex in a vectorized manner.
    64  func (defCaus *CorrelatedDeferredCauset) VecEvalDecimal(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    65  	return genVecFromConstExpr(ctx, defCaus, types.ETDecimal, input, result)
    66  }
    67  
    68  // VecEvalTime evaluates this memex in a vectorized manner.
    69  func (defCaus *CorrelatedDeferredCauset) VecEvalTime(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    70  	return genVecFromConstExpr(ctx, defCaus, types.ETTimestamp, input, result)
    71  }
    72  
    73  // VecEvalDuration evaluates this memex in a vectorized manner.
    74  func (defCaus *CorrelatedDeferredCauset) VecEvalDuration(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    75  	return genVecFromConstExpr(ctx, defCaus, types.ETDuration, input, result)
    76  }
    77  
    78  // VecEvalJSON evaluates this memex in a vectorized manner.
    79  func (defCaus *CorrelatedDeferredCauset) VecEvalJSON(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
    80  	return genVecFromConstExpr(ctx, defCaus, types.ETJson, input, result)
    81  }
    82  
    83  // Eval implements Expression interface.
    84  func (defCaus *CorrelatedDeferredCauset) Eval(event chunk.Event) (types.Causet, error) {
    85  	return *defCaus.Data, nil
    86  }
    87  
    88  // EvalInt returns int representation of CorrelatedDeferredCauset.
    89  func (defCaus *CorrelatedDeferredCauset) EvalInt(ctx stochastikctx.Context, event chunk.Event) (int64, bool, error) {
    90  	if defCaus.Data.IsNull() {
    91  		return 0, true, nil
    92  	}
    93  	if defCaus.GetType().Hybrid() {
    94  		res, err := defCaus.Data.ToInt64(ctx.GetStochastikVars().StmtCtx)
    95  		return res, err != nil, err
    96  	}
    97  	return defCaus.Data.GetInt64(), false, nil
    98  }
    99  
   100  // EvalReal returns real representation of CorrelatedDeferredCauset.
   101  func (defCaus *CorrelatedDeferredCauset) EvalReal(ctx stochastikctx.Context, event chunk.Event) (float64, bool, error) {
   102  	if defCaus.Data.IsNull() {
   103  		return 0, true, nil
   104  	}
   105  	return defCaus.Data.GetFloat64(), false, nil
   106  }
   107  
   108  // EvalString returns string representation of CorrelatedDeferredCauset.
   109  func (defCaus *CorrelatedDeferredCauset) EvalString(ctx stochastikctx.Context, event chunk.Event) (string, bool, error) {
   110  	if defCaus.Data.IsNull() {
   111  		return "", true, nil
   112  	}
   113  	res, err := defCaus.Data.ToString()
   114  	return res, err != nil, err
   115  }
   116  
   117  // EvalDecimal returns decimal representation of CorrelatedDeferredCauset.
   118  func (defCaus *CorrelatedDeferredCauset) EvalDecimal(ctx stochastikctx.Context, event chunk.Event) (*types.MyDecimal, bool, error) {
   119  	if defCaus.Data.IsNull() {
   120  		return nil, true, nil
   121  	}
   122  	return defCaus.Data.GetMysqlDecimal(), false, nil
   123  }
   124  
   125  // EvalTime returns DATE/DATETIME/TIMESTAMP representation of CorrelatedDeferredCauset.
   126  func (defCaus *CorrelatedDeferredCauset) EvalTime(ctx stochastikctx.Context, event chunk.Event) (types.Time, bool, error) {
   127  	if defCaus.Data.IsNull() {
   128  		return types.ZeroTime, true, nil
   129  	}
   130  	return defCaus.Data.GetMysqlTime(), false, nil
   131  }
   132  
   133  // EvalDuration returns Duration representation of CorrelatedDeferredCauset.
   134  func (defCaus *CorrelatedDeferredCauset) EvalDuration(ctx stochastikctx.Context, event chunk.Event) (types.Duration, bool, error) {
   135  	if defCaus.Data.IsNull() {
   136  		return types.Duration{}, true, nil
   137  	}
   138  	return defCaus.Data.GetMysqlDuration(), false, nil
   139  }
   140  
   141  // EvalJSON returns JSON representation of CorrelatedDeferredCauset.
   142  func (defCaus *CorrelatedDeferredCauset) EvalJSON(ctx stochastikctx.Context, event chunk.Event) (json.BinaryJSON, bool, error) {
   143  	if defCaus.Data.IsNull() {
   144  		return json.BinaryJSON{}, true, nil
   145  	}
   146  	return defCaus.Data.GetMysqlJSON(), false, nil
   147  }
   148  
   149  // Equal implements Expression interface.
   150  func (defCaus *CorrelatedDeferredCauset) Equal(ctx stochastikctx.Context, expr Expression) bool {
   151  	if cc, ok := expr.(*CorrelatedDeferredCauset); ok {
   152  		return defCaus.DeferredCauset.Equal(ctx, &cc.DeferredCauset)
   153  	}
   154  	return false
   155  }
   156  
   157  // IsCorrelated implements Expression interface.
   158  func (defCaus *CorrelatedDeferredCauset) IsCorrelated() bool {
   159  	return true
   160  }
   161  
   162  // ConstItem implements Expression interface.
   163  func (defCaus *CorrelatedDeferredCauset) ConstItem(_ *stmtctx.StatementContext) bool {
   164  	return false
   165  }
   166  
   167  // Decorrelate implements Expression interface.
   168  func (defCaus *CorrelatedDeferredCauset) Decorrelate(schemaReplicant *Schema) Expression {
   169  	if !schemaReplicant.Contains(&defCaus.DeferredCauset) {
   170  		return defCaus
   171  	}
   172  	return &defCaus.DeferredCauset
   173  }
   174  
   175  // ResolveIndices implements Expression interface.
   176  func (defCaus *CorrelatedDeferredCauset) ResolveIndices(_ *Schema) (Expression, error) {
   177  	return defCaus, nil
   178  }
   179  
   180  func (defCaus *CorrelatedDeferredCauset) resolveIndices(_ *Schema) error {
   181  	return nil
   182  }
   183  
   184  // DeferredCauset represents a defCausumn.
   185  type DeferredCauset struct {
   186  	RetType *types.FieldType
   187  	// ID is used to specify whether this defCausumn is ExtraHandleDeferredCauset or to access histogram.
   188  	// We'll try to remove it in the future.
   189  	ID int64
   190  	// UniqueID is the unique id of this defCausumn.
   191  	UniqueID int64
   192  
   193  	// Index is used for execution, to tell the defCausumn's position in the given event.
   194  	Index int
   195  
   196  	hashcode []byte
   197  
   198  	// VirtualExpr is used to save memex for virtual defCausumn
   199  	VirtualExpr Expression
   200  
   201  	OrigName string
   202  	IsHidden bool
   203  
   204  	// InOperand indicates whether this defCausumn is the inner operand of defCausumn equal condition converted
   205  	// from `[not] in (subq)`.
   206  	InOperand bool
   207  
   208  	defCauslationInfo
   209  }
   210  
   211  // Equal implements Expression interface.
   212  func (defCaus *DeferredCauset) Equal(_ stochastikctx.Context, expr Expression) bool {
   213  	if newDefCaus, ok := expr.(*DeferredCauset); ok {
   214  		return newDefCaus.UniqueID == defCaus.UniqueID
   215  	}
   216  	return false
   217  }
   218  
   219  // VecEvalInt evaluates this memex in a vectorized manner.
   220  func (defCaus *DeferredCauset) VecEvalInt(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   221  	if defCaus.RetType.Hybrid() {
   222  		it := chunk.NewIterator4Chunk(input)
   223  		result.ResizeInt64(0, false)
   224  		for event := it.Begin(); event != it.End(); event = it.Next() {
   225  			v, null, err := defCaus.EvalInt(ctx, event)
   226  			if err != nil {
   227  				return err
   228  			}
   229  			if null {
   230  				result.AppendNull()
   231  			} else {
   232  				result.AppendInt64(v)
   233  			}
   234  		}
   235  		return nil
   236  	}
   237  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   238  	return nil
   239  }
   240  
   241  // VecEvalReal evaluates this memex in a vectorized manner.
   242  func (defCaus *DeferredCauset) VecEvalReal(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   243  	n := input.NumEvents()
   244  	src := input.DeferredCauset(defCaus.Index)
   245  	if defCaus.GetType().Tp == allegrosql.TypeFloat {
   246  		result.ResizeFloat64(n, false)
   247  		f32s := src.Float32s()
   248  		f64s := result.Float64s()
   249  		sel := input.Sel()
   250  		if sel != nil {
   251  			for i, j := range sel {
   252  				if src.IsNull(j) {
   253  					result.SetNull(i, true)
   254  				} else {
   255  					f64s[i] = float64(f32s[j])
   256  				}
   257  			}
   258  			return nil
   259  		}
   260  		for i := range f32s {
   261  			// TODO(zhangyuanjia): speed up the way to manipulate null-bitmaps.
   262  			if src.IsNull(i) {
   263  				result.SetNull(i, true)
   264  			} else {
   265  				f64s[i] = float64(f32s[i])
   266  			}
   267  		}
   268  		return nil
   269  	}
   270  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   271  	return nil
   272  }
   273  
   274  // VecEvalString evaluates this memex in a vectorized manner.
   275  func (defCaus *DeferredCauset) VecEvalString(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   276  	if defCaus.RetType.Hybrid() {
   277  		it := chunk.NewIterator4Chunk(input)
   278  		result.ReserveString(input.NumEvents())
   279  		for event := it.Begin(); event != it.End(); event = it.Next() {
   280  			v, null, err := defCaus.EvalString(ctx, event)
   281  			if err != nil {
   282  				return err
   283  			}
   284  			if null {
   285  				result.AppendNull()
   286  			} else {
   287  				result.AppendString(v)
   288  			}
   289  		}
   290  		return nil
   291  	}
   292  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   293  	return nil
   294  }
   295  
   296  // VecEvalDecimal evaluates this memex in a vectorized manner.
   297  func (defCaus *DeferredCauset) VecEvalDecimal(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   298  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   299  	return nil
   300  }
   301  
   302  // VecEvalTime evaluates this memex in a vectorized manner.
   303  func (defCaus *DeferredCauset) VecEvalTime(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   304  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   305  	return nil
   306  }
   307  
   308  // VecEvalDuration evaluates this memex in a vectorized manner.
   309  func (defCaus *DeferredCauset) VecEvalDuration(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   310  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   311  	return nil
   312  }
   313  
   314  // VecEvalJSON evaluates this memex in a vectorized manner.
   315  func (defCaus *DeferredCauset) VecEvalJSON(ctx stochastikctx.Context, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   316  	input.DeferredCauset(defCaus.Index).CopyReconstruct(input.Sel(), result)
   317  	return nil
   318  }
   319  
   320  const defCausumnPrefix = "DeferredCauset#"
   321  
   322  // String implements Stringer interface.
   323  func (defCaus *DeferredCauset) String() string {
   324  	if defCaus.OrigName != "" {
   325  		return defCaus.OrigName
   326  	}
   327  	var builder strings.Builder
   328  	fmt.Fprintf(&builder, "%s%d", defCausumnPrefix, defCaus.UniqueID)
   329  	return builder.String()
   330  }
   331  
   332  // MarshalJSON implements json.Marshaler interface.
   333  func (defCaus *DeferredCauset) MarshalJSON() ([]byte, error) {
   334  	return []byte(fmt.Sprintf("%q", defCaus)), nil
   335  }
   336  
   337  // GetType implements Expression interface.
   338  func (defCaus *DeferredCauset) GetType() *types.FieldType {
   339  	return defCaus.RetType
   340  }
   341  
   342  // Eval implements Expression interface.
   343  func (defCaus *DeferredCauset) Eval(event chunk.Event) (types.Causet, error) {
   344  	return event.GetCauset(defCaus.Index, defCaus.RetType), nil
   345  }
   346  
   347  // EvalInt returns int representation of DeferredCauset.
   348  func (defCaus *DeferredCauset) EvalInt(ctx stochastikctx.Context, event chunk.Event) (int64, bool, error) {
   349  	if defCaus.GetType().Hybrid() {
   350  		val := event.GetCauset(defCaus.Index, defCaus.RetType)
   351  		if val.IsNull() {
   352  			return 0, true, nil
   353  		}
   354  		if val.HoTT() == types.HoTTMysqlBit {
   355  			val, err := val.GetBinaryLiteral().ToInt(ctx.GetStochastikVars().StmtCtx)
   356  			return int64(val), err != nil, err
   357  		}
   358  		res, err := val.ToInt64(ctx.GetStochastikVars().StmtCtx)
   359  		return res, err != nil, err
   360  	}
   361  	if event.IsNull(defCaus.Index) {
   362  		return 0, true, nil
   363  	}
   364  	return event.GetInt64(defCaus.Index), false, nil
   365  }
   366  
   367  // EvalReal returns real representation of DeferredCauset.
   368  func (defCaus *DeferredCauset) EvalReal(ctx stochastikctx.Context, event chunk.Event) (float64, bool, error) {
   369  	if event.IsNull(defCaus.Index) {
   370  		return 0, true, nil
   371  	}
   372  	if defCaus.GetType().Tp == allegrosql.TypeFloat {
   373  		return float64(event.GetFloat32(defCaus.Index)), false, nil
   374  	}
   375  	return event.GetFloat64(defCaus.Index), false, nil
   376  }
   377  
   378  // EvalString returns string representation of DeferredCauset.
   379  func (defCaus *DeferredCauset) EvalString(ctx stochastikctx.Context, event chunk.Event) (string, bool, error) {
   380  	if event.IsNull(defCaus.Index) {
   381  		return "", true, nil
   382  	}
   383  
   384  	// Specially handle the ENUM/SET/BIT input value.
   385  	if defCaus.GetType().Hybrid() {
   386  		val := event.GetCauset(defCaus.Index, defCaus.RetType)
   387  		res, err := val.ToString()
   388  		return res, err != nil, err
   389  	}
   390  
   391  	val := event.GetString(defCaus.Index)
   392  	return val, false, nil
   393  }
   394  
   395  // EvalDecimal returns decimal representation of DeferredCauset.
   396  func (defCaus *DeferredCauset) EvalDecimal(ctx stochastikctx.Context, event chunk.Event) (*types.MyDecimal, bool, error) {
   397  	if event.IsNull(defCaus.Index) {
   398  		return nil, true, nil
   399  	}
   400  	return event.GetMyDecimal(defCaus.Index), false, nil
   401  }
   402  
   403  // EvalTime returns DATE/DATETIME/TIMESTAMP representation of DeferredCauset.
   404  func (defCaus *DeferredCauset) EvalTime(ctx stochastikctx.Context, event chunk.Event) (types.Time, bool, error) {
   405  	if event.IsNull(defCaus.Index) {
   406  		return types.ZeroTime, true, nil
   407  	}
   408  	return event.GetTime(defCaus.Index), false, nil
   409  }
   410  
   411  // EvalDuration returns Duration representation of DeferredCauset.
   412  func (defCaus *DeferredCauset) EvalDuration(ctx stochastikctx.Context, event chunk.Event) (types.Duration, bool, error) {
   413  	if event.IsNull(defCaus.Index) {
   414  		return types.Duration{}, true, nil
   415  	}
   416  	duration := event.GetDuration(defCaus.Index, defCaus.RetType.Decimal)
   417  	return duration, false, nil
   418  }
   419  
   420  // EvalJSON returns JSON representation of DeferredCauset.
   421  func (defCaus *DeferredCauset) EvalJSON(ctx stochastikctx.Context, event chunk.Event) (json.BinaryJSON, bool, error) {
   422  	if event.IsNull(defCaus.Index) {
   423  		return json.BinaryJSON{}, true, nil
   424  	}
   425  	return event.GetJSON(defCaus.Index), false, nil
   426  }
   427  
   428  // Clone implements Expression interface.
   429  func (defCaus *DeferredCauset) Clone() Expression {
   430  	newDefCaus := *defCaus
   431  	return &newDefCaus
   432  }
   433  
   434  // IsCorrelated implements Expression interface.
   435  func (defCaus *DeferredCauset) IsCorrelated() bool {
   436  	return false
   437  }
   438  
   439  // ConstItem implements Expression interface.
   440  func (defCaus *DeferredCauset) ConstItem(_ *stmtctx.StatementContext) bool {
   441  	return false
   442  }
   443  
   444  // Decorrelate implements Expression interface.
   445  func (defCaus *DeferredCauset) Decorrelate(_ *Schema) Expression {
   446  	return defCaus
   447  }
   448  
   449  // HashCode implements Expression interface.
   450  func (defCaus *DeferredCauset) HashCode(_ *stmtctx.StatementContext) []byte {
   451  	if len(defCaus.hashcode) != 0 {
   452  		return defCaus.hashcode
   453  	}
   454  	defCaus.hashcode = make([]byte, 0, 9)
   455  	defCaus.hashcode = append(defCaus.hashcode, defCausumnFlag)
   456  	defCaus.hashcode = codec.EncodeInt(defCaus.hashcode, defCaus.UniqueID)
   457  	return defCaus.hashcode
   458  }
   459  
   460  // ResolveIndices implements Expression interface.
   461  func (defCaus *DeferredCauset) ResolveIndices(schemaReplicant *Schema) (Expression, error) {
   462  	newDefCaus := defCaus.Clone()
   463  	err := newDefCaus.resolveIndices(schemaReplicant)
   464  	return newDefCaus, err
   465  }
   466  
   467  func (defCaus *DeferredCauset) resolveIndices(schemaReplicant *Schema) error {
   468  	defCaus.Index = schemaReplicant.DeferredCausetIndex(defCaus)
   469  	if defCaus.Index == -1 {
   470  		return errors.Errorf("Can't find defCausumn %s in schemaReplicant %s", defCaus, schemaReplicant)
   471  	}
   472  	return nil
   473  }
   474  
   475  // Vectorized returns if this memex supports vectorized evaluation.
   476  func (defCaus *DeferredCauset) Vectorized() bool {
   477  	return true
   478  }
   479  
   480  // ToInfo converts the memex.DeferredCauset to perceptron.DeferredCausetInfo for casting values,
   481  // beware it doesn't fill all the fields of the perceptron.DeferredCausetInfo.
   482  func (defCaus *DeferredCauset) ToInfo() *perceptron.DeferredCausetInfo {
   483  	return &perceptron.DeferredCausetInfo{
   484  		ID:        defCaus.ID,
   485  		FieldType: *defCaus.RetType,
   486  	}
   487  }
   488  
   489  // DeferredCauset2Exprs will transfer defCausumn slice to memex slice.
   490  func DeferredCauset2Exprs(defcaus []*DeferredCauset) []Expression {
   491  	result := make([]Expression, 0, len(defcaus))
   492  	for _, defCaus := range defcaus {
   493  		result = append(result, defCaus)
   494  	}
   495  	return result
   496  }
   497  
   498  // DefCausInfo2DefCaus finds the corresponding defCausumn of the DeferredCausetInfo in a defCausumn slice.
   499  func DefCausInfo2DefCaus(defcaus []*DeferredCauset, defCaus *perceptron.DeferredCausetInfo) *DeferredCauset {
   500  	for _, c := range defcaus {
   501  		if c.ID == defCaus.ID {
   502  			return c
   503  		}
   504  	}
   505  	return nil
   506  }
   507  
   508  // indexDefCaus2DefCaus finds the corresponding defCausumn of the IndexDeferredCauset in a defCausumn slice.
   509  func indexDefCaus2DefCaus(defCausInfos []*perceptron.DeferredCausetInfo, defcaus []*DeferredCauset, defCaus *perceptron.IndexDeferredCauset) *DeferredCauset {
   510  	for i, info := range defCausInfos {
   511  		if info.Name.L == defCaus.Name.L {
   512  			return defcaus[i]
   513  		}
   514  	}
   515  	return nil
   516  }
   517  
   518  // IndexInfo2PrefixDefCauss gets the corresponding []*DeferredCauset of the indexInfo's []*IndexDeferredCauset,
   519  // together with a []int containing their lengths.
   520  // If this index has three IndexDeferredCauset that the 1st and 3rd IndexDeferredCauset has corresponding *DeferredCauset,
   521  // the return value will be only the 1st corresponding *DeferredCauset and its length.
   522  // TODO: Use a struct to represent {*DeferredCauset, int}. And merge IndexInfo2PrefixDefCauss and IndexInfo2DefCauss.
   523  func IndexInfo2PrefixDefCauss(defCausInfos []*perceptron.DeferredCausetInfo, defcaus []*DeferredCauset, index *perceptron.IndexInfo) ([]*DeferredCauset, []int) {
   524  	retDefCauss := make([]*DeferredCauset, 0, len(index.DeferredCausets))
   525  	lengths := make([]int, 0, len(index.DeferredCausets))
   526  	for _, c := range index.DeferredCausets {
   527  		defCaus := indexDefCaus2DefCaus(defCausInfos, defcaus, c)
   528  		if defCaus == nil {
   529  			return retDefCauss, lengths
   530  		}
   531  		retDefCauss = append(retDefCauss, defCaus)
   532  		if c.Length != types.UnspecifiedLength && c.Length == defCaus.RetType.Flen {
   533  			lengths = append(lengths, types.UnspecifiedLength)
   534  		} else {
   535  			lengths = append(lengths, c.Length)
   536  		}
   537  	}
   538  	return retDefCauss, lengths
   539  }
   540  
   541  // IndexInfo2DefCauss gets the corresponding []*DeferredCauset of the indexInfo's []*IndexDeferredCauset,
   542  // together with a []int containing their lengths.
   543  // If this index has three IndexDeferredCauset that the 1st and 3rd IndexDeferredCauset has corresponding *DeferredCauset,
   544  // the return value will be [defCaus1, nil, defCaus2].
   545  func IndexInfo2DefCauss(defCausInfos []*perceptron.DeferredCausetInfo, defcaus []*DeferredCauset, index *perceptron.IndexInfo) ([]*DeferredCauset, []int) {
   546  	retDefCauss := make([]*DeferredCauset, 0, len(index.DeferredCausets))
   547  	lens := make([]int, 0, len(index.DeferredCausets))
   548  	for _, c := range index.DeferredCausets {
   549  		defCaus := indexDefCaus2DefCaus(defCausInfos, defcaus, c)
   550  		if defCaus == nil {
   551  			retDefCauss = append(retDefCauss, defCaus)
   552  			lens = append(lens, types.UnspecifiedLength)
   553  			continue
   554  		}
   555  		retDefCauss = append(retDefCauss, defCaus)
   556  		if c.Length != types.UnspecifiedLength && c.Length == defCaus.RetType.Flen {
   557  			lens = append(lens, types.UnspecifiedLength)
   558  		} else {
   559  			lens = append(lens, c.Length)
   560  		}
   561  	}
   562  	return retDefCauss, lens
   563  }
   564  
   565  // FindPrefixOfIndex will find defCausumns in index by checking the unique id.
   566  // So it will return at once no matching defCausumn is found.
   567  func FindPrefixOfIndex(defcaus []*DeferredCauset, idxDefCausIDs []int64) []*DeferredCauset {
   568  	retDefCauss := make([]*DeferredCauset, 0, len(idxDefCausIDs))
   569  idLoop:
   570  	for _, id := range idxDefCausIDs {
   571  		for _, defCaus := range defcaus {
   572  			if defCaus.UniqueID == id {
   573  				retDefCauss = append(retDefCauss, defCaus)
   574  				continue idLoop
   575  			}
   576  		}
   577  		// If no matching defCausumn is found, just return.
   578  		return retDefCauss
   579  	}
   580  	return retDefCauss
   581  }
   582  
   583  // EvalVirtualDeferredCauset evals the virtual defCausumn
   584  func (defCaus *DeferredCauset) EvalVirtualDeferredCauset(event chunk.Event) (types.Causet, error) {
   585  	return defCaus.VirtualExpr.Eval(event)
   586  }
   587  
   588  // SupportReverseEval checks whether the builtinFunc support reverse evaluation.
   589  func (defCaus *DeferredCauset) SupportReverseEval() bool {
   590  	switch defCaus.RetType.Tp {
   591  	case allegrosql.TypeShort, allegrosql.TypeLong, allegrosql.TypeLonglong,
   592  		allegrosql.TypeFloat, allegrosql.TypeDouble, allegrosql.TypeNewDecimal:
   593  		return true
   594  	}
   595  	return false
   596  }
   597  
   598  // ReverseEval evaluates the only one defCausumn value with given function result.
   599  func (defCaus *DeferredCauset) ReverseEval(sc *stmtctx.StatementContext, res types.Causet, rType types.RoundingType) (val types.Causet, err error) {
   600  	return types.ChangeReverseResultByUpperLowerBound(sc, defCaus.RetType, res, rType)
   601  }
   602  
   603  // Coercibility returns the coercibility value which is used to check defCauslations.
   604  func (defCaus *DeferredCauset) Coercibility() Coercibility {
   605  	if defCaus.HasCoercibility() {
   606  		return defCaus.defCauslationInfo.Coercibility()
   607  	}
   608  	defCaus.SetCoercibility(deriveCoercibilityForDeferredCauset(defCaus))
   609  	return defCaus.defCauslationInfo.Coercibility()
   610  }
   611  
   612  // SortDeferredCausets sort defCausumns based on UniqueID.
   613  func SortDeferredCausets(defcaus []*DeferredCauset) []*DeferredCauset {
   614  	sorted := make([]*DeferredCauset, len(defcaus))
   615  	copy(sorted, defcaus)
   616  	sort.Slice(sorted, func(i, j int) bool {
   617  		return sorted[i].UniqueID < sorted[j].UniqueID
   618  	})
   619  	return sorted
   620  }