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 }