github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/physical_plans.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 embedded 15 16 import ( 17 "unsafe" 18 19 "github.com/whtcorpsinc/BerolinaSQL/ast" 20 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 21 "github.com/whtcorpsinc/errors" 22 "github.com/whtcorpsinc/milevadb/causet" 23 "github.com/whtcorpsinc/milevadb/causet/property" 24 "github.com/whtcorpsinc/milevadb/causet/soliton" 25 "github.com/whtcorpsinc/milevadb/ekv" 26 "github.com/whtcorpsinc/milevadb/memex" 27 "github.com/whtcorpsinc/milevadb/memex/aggregation" 28 "github.com/whtcorpsinc/milevadb/soliton/ranger" 29 "github.com/whtcorpsinc/milevadb/statistics" 30 "github.com/whtcorpsinc/milevadb/stochastikctx" 31 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 32 "github.com/whtcorpsinc/milevadb/types" 33 ) 34 35 var ( 36 _ PhysicalCauset = &PhysicalSelection{} 37 _ PhysicalCauset = &PhysicalProjection{} 38 _ PhysicalCauset = &PhysicalTopN{} 39 _ PhysicalCauset = &PhysicalMaxOneRow{} 40 _ PhysicalCauset = &PhysicalBlockDual{} 41 _ PhysicalCauset = &PhysicalUnionAll{} 42 _ PhysicalCauset = &PhysicalSort{} 43 _ PhysicalCauset = &NominalSort{} 44 _ PhysicalCauset = &PhysicalLock{} 45 _ PhysicalCauset = &PhysicalLimit{} 46 _ PhysicalCauset = &PhysicalIndexScan{} 47 _ PhysicalCauset = &PhysicalBlockScan{} 48 _ PhysicalCauset = &PhysicalBlockReader{} 49 _ PhysicalCauset = &PhysicalIndexReader{} 50 _ PhysicalCauset = &PhysicalIndexLookUpReader{} 51 _ PhysicalCauset = &PhysicalIndexMergeReader{} 52 _ PhysicalCauset = &PhysicalHashAgg{} 53 _ PhysicalCauset = &PhysicalStreamAgg{} 54 _ PhysicalCauset = &PhysicalApply{} 55 _ PhysicalCauset = &PhysicalIndexJoin{} 56 _ PhysicalCauset = &PhysicalBroadCastJoin{} 57 _ PhysicalCauset = &PhysicalHashJoin{} 58 _ PhysicalCauset = &PhysicalMergeJoin{} 59 _ PhysicalCauset = &PhysicalUnionScan{} 60 _ PhysicalCauset = &PhysicalWindow{} 61 _ PhysicalCauset = &PhysicalShuffle{} 62 _ PhysicalCauset = &PhysicalShuffleDataSourceStub{} 63 _ PhysicalCauset = &BatchPointGetCauset{} 64 ) 65 66 // PhysicalBlockReader is the causet reader in milevadb. 67 type PhysicalBlockReader struct { 68 physicalSchemaProducer 69 70 // BlockCausets flats the blockCauset to construct interlock pb. 71 BlockCausets []PhysicalCauset 72 blockCauset PhysicalCauset 73 74 // StoreType indicates causet read from which type of causetstore. 75 StoreType ekv.StoreType 76 77 IsCommonHandle bool 78 79 // Used by partition causet. 80 PartitionInfo PartitionInfo 81 } 82 83 // PartitionInfo indicates partition helper info in physical plan. 84 type PartitionInfo struct { 85 PruningConds []memex.Expression 86 PartitionNames []perceptron.CIStr 87 DeferredCausets []*memex.DeferredCauset 88 DeferredCausetNames types.NameSlice 89 } 90 91 // GetBlockCauset exports the blockCauset. 92 func (p *PhysicalBlockReader) GetBlockCauset() PhysicalCauset { 93 return p.blockCauset 94 } 95 96 // GetBlockScan exports the blockScan that contained in blockCauset. 97 func (p *PhysicalBlockReader) GetBlockScan() *PhysicalBlockScan { 98 curCauset := p.blockCauset 99 for { 100 chCnt := len(curCauset.Children()) 101 if chCnt == 0 { 102 return curCauset.(*PhysicalBlockScan) 103 } else if chCnt == 1 { 104 curCauset = curCauset.Children()[0] 105 } else { 106 join := curCauset.(*PhysicalBroadCastJoin) 107 curCauset = join.children[1-join.globalChildIndex] 108 } 109 } 110 } 111 112 // GetPhysicalBlockReader returns PhysicalBlockReader for logical EinsteinDBSingleGather. 113 func (sg *EinsteinDBSingleGather) GetPhysicalBlockReader(schemaReplicant *memex.Schema, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalBlockReader { 114 reader := PhysicalBlockReader{}.Init(sg.ctx, sg.blockOffset) 115 reader.PartitionInfo = PartitionInfo{ 116 PruningConds: sg.Source.allConds, 117 PartitionNames: sg.Source.partitionNames, 118 DeferredCausets: sg.Source.TblDefCauss, 119 DeferredCausetNames: sg.Source.names, 120 } 121 reader.stats = stats 122 reader.SetSchema(schemaReplicant) 123 reader.childrenReqProps = props 124 return reader 125 } 126 127 // GetPhysicalIndexReader returns PhysicalIndexReader for logical EinsteinDBSingleGather. 128 func (sg *EinsteinDBSingleGather) GetPhysicalIndexReader(schemaReplicant *memex.Schema, stats *property.StatsInfo, props ...*property.PhysicalProperty) *PhysicalIndexReader { 129 reader := PhysicalIndexReader{}.Init(sg.ctx, sg.blockOffset) 130 reader.stats = stats 131 reader.SetSchema(schemaReplicant) 132 reader.childrenReqProps = props 133 return reader 134 } 135 136 // Clone implements PhysicalCauset interface. 137 func (p *PhysicalBlockReader) Clone() (PhysicalCauset, error) { 138 cloned := new(PhysicalBlockReader) 139 base, err := p.physicalSchemaProducer.cloneWithSelf(cloned) 140 if err != nil { 141 return nil, err 142 } 143 cloned.physicalSchemaProducer = *base 144 cloned.StoreType = p.StoreType 145 cloned.IsCommonHandle = p.IsCommonHandle 146 if cloned.blockCauset, err = p.blockCauset.Clone(); err != nil { 147 return nil, err 148 } 149 if cloned.BlockCausets, err = clonePhysicalCauset(p.BlockCausets); err != nil { 150 return nil, err 151 } 152 return cloned, nil 153 } 154 155 // SetChildren overrides PhysicalCauset SetChildren interface. 156 func (p *PhysicalBlockReader) SetChildren(children ...PhysicalCauset) { 157 p.blockCauset = children[0] 158 p.BlockCausets = flattenPushDownCauset(p.blockCauset) 159 } 160 161 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 162 func (p *PhysicalBlockReader) ExtractCorrelatedDefCauss() (corDefCauss []*memex.CorrelatedDeferredCauset) { 163 for _, child := range p.BlockCausets { 164 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 165 } 166 return corDefCauss 167 } 168 169 // PhysicalIndexReader is the index reader in milevadb. 170 type PhysicalIndexReader struct { 171 physicalSchemaProducer 172 173 // IndexCausets flats the indexCauset to construct interlock pb. 174 IndexCausets []PhysicalCauset 175 indexCauset PhysicalCauset 176 177 // OutputDeferredCausets represents the columns that index reader should return. 178 OutputDeferredCausets []*memex.DeferredCauset 179 180 // Used by partition causet. 181 PartitionInfo PartitionInfo 182 } 183 184 // Clone implements PhysicalCauset interface. 185 func (p *PhysicalIndexReader) Clone() (PhysicalCauset, error) { 186 cloned := new(PhysicalIndexReader) 187 base, err := p.physicalSchemaProducer.cloneWithSelf(cloned) 188 if err != nil { 189 return nil, err 190 } 191 cloned.physicalSchemaProducer = *base 192 if cloned.indexCauset, err = p.indexCauset.Clone(); err != nil { 193 return nil, err 194 } 195 if cloned.IndexCausets, err = clonePhysicalCauset(p.IndexCausets); err != nil { 196 return nil, err 197 } 198 cloned.OutputDeferredCausets = cloneDefCauss(p.OutputDeferredCausets) 199 return cloned, err 200 } 201 202 // SetSchema overrides PhysicalCauset SetSchema interface. 203 func (p *PhysicalIndexReader) SetSchema(_ *memex.Schema) { 204 if p.indexCauset != nil { 205 p.IndexCausets = flattenPushDownCauset(p.indexCauset) 206 switch p.indexCauset.(type) { 207 case *PhysicalHashAgg, *PhysicalStreamAgg: 208 p.schemaReplicant = p.indexCauset.Schema() 209 default: 210 is := p.IndexCausets[0].(*PhysicalIndexScan) 211 p.schemaReplicant = is.dataSourceSchema 212 } 213 p.OutputDeferredCausets = p.schemaReplicant.Clone().DeferredCausets 214 } 215 } 216 217 // SetChildren overrides PhysicalCauset SetChildren interface. 218 func (p *PhysicalIndexReader) SetChildren(children ...PhysicalCauset) { 219 p.indexCauset = children[0] 220 p.SetSchema(nil) 221 } 222 223 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 224 func (p *PhysicalIndexReader) ExtractCorrelatedDefCauss() (corDefCauss []*memex.CorrelatedDeferredCauset) { 225 for _, child := range p.IndexCausets { 226 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 227 } 228 return corDefCauss 229 } 230 231 // PushedDownLimit is the limit operator pushed down into PhysicalIndexLookUpReader. 232 type PushedDownLimit struct { 233 Offset uint64 234 Count uint64 235 } 236 237 // Clone clones this pushed-down list. 238 func (p *PushedDownLimit) Clone() *PushedDownLimit { 239 cloned := new(PushedDownLimit) 240 *cloned = *p 241 return cloned 242 } 243 244 // PhysicalIndexLookUpReader is the index look up reader in milevadb. It's used in case of double reading. 245 type PhysicalIndexLookUpReader struct { 246 physicalSchemaProducer 247 248 // IndexCausets flats the indexCauset to construct interlock pb. 249 IndexCausets []PhysicalCauset 250 // BlockCausets flats the blockCauset to construct interlock pb. 251 BlockCausets []PhysicalCauset 252 indexCauset PhysicalCauset 253 blockCauset PhysicalCauset 254 255 ExtraHandleDefCaus *memex.DeferredCauset 256 // PushedLimit is used to avoid unnecessary causet scan tasks of IndexLookUpReader. 257 PushedLimit *PushedDownLimit 258 259 CommonHandleDefCauss []*memex.DeferredCauset 260 261 // Used by partition causet. 262 PartitionInfo PartitionInfo 263 } 264 265 // Clone implements PhysicalCauset interface. 266 func (p *PhysicalIndexLookUpReader) Clone() (PhysicalCauset, error) { 267 cloned := new(PhysicalIndexLookUpReader) 268 base, err := p.physicalSchemaProducer.cloneWithSelf(cloned) 269 if err != nil { 270 return nil, err 271 } 272 cloned.physicalSchemaProducer = *base 273 if cloned.IndexCausets, err = clonePhysicalCauset(p.IndexCausets); err != nil { 274 return nil, err 275 } 276 if cloned.BlockCausets, err = clonePhysicalCauset(p.BlockCausets); err != nil { 277 return nil, err 278 } 279 if cloned.indexCauset, err = p.indexCauset.Clone(); err != nil { 280 return nil, err 281 } 282 if cloned.blockCauset, err = p.blockCauset.Clone(); err != nil { 283 return nil, err 284 } 285 if p.ExtraHandleDefCaus != nil { 286 cloned.ExtraHandleDefCaus = p.ExtraHandleDefCaus.Clone().(*memex.DeferredCauset) 287 } 288 if p.PushedLimit != nil { 289 cloned.PushedLimit = p.PushedLimit.Clone() 290 } 291 return cloned, nil 292 } 293 294 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 295 func (p *PhysicalIndexLookUpReader) ExtractCorrelatedDefCauss() (corDefCauss []*memex.CorrelatedDeferredCauset) { 296 for _, child := range p.BlockCausets { 297 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 298 } 299 for _, child := range p.IndexCausets { 300 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 301 } 302 return corDefCauss 303 } 304 305 // PhysicalIndexMergeReader is the reader using multiple indexes in milevadb. 306 type PhysicalIndexMergeReader struct { 307 physicalSchemaProducer 308 309 // PartialCausets flats the partialCausets to construct interlock pb. 310 PartialCausets [][]PhysicalCauset 311 // BlockCausets flats the blockCauset to construct interlock pb. 312 BlockCausets []PhysicalCauset 313 // partialCausets are the partial plans that have not been flatted. The type of each element is permitted PhysicalIndexScan or PhysicalBlockScan. 314 partialCausets []PhysicalCauset 315 // blockCauset is a PhysicalBlockScan to get the causet tuples. Current, it must be not nil. 316 blockCauset PhysicalCauset 317 318 // Used by partition causet. 319 PartitionInfo PartitionInfo 320 } 321 322 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 323 func (p *PhysicalIndexMergeReader) ExtractCorrelatedDefCauss() (corDefCauss []*memex.CorrelatedDeferredCauset) { 324 for _, child := range p.BlockCausets { 325 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 326 } 327 for _, child := range p.partialCausets { 328 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 329 } 330 for _, PartialCauset := range p.PartialCausets { 331 for _, child := range PartialCauset { 332 corDefCauss = append(corDefCauss, ExtractCorrelatedDefCauss4PhysicalCauset(child)...) 333 } 334 } 335 return corDefCauss 336 } 337 338 // PhysicalIndexScan represents an index scan plan. 339 type PhysicalIndexScan struct { 340 physicalSchemaProducer 341 342 // AccessCondition is used to calculate range. 343 AccessCondition []memex.Expression 344 345 Block *perceptron.BlockInfo 346 Index *perceptron.IndexInfo 347 IdxDefCauss []*memex.DeferredCauset 348 IdxDefCausLens []int 349 Ranges []*ranger.Range 350 DeferredCausets []*perceptron.DeferredCausetInfo 351 DBName perceptron.CIStr 352 353 BlockAsName *perceptron.CIStr 354 355 // dataSourceSchema is the original schemaReplicant of DataSource. The schemaReplicant of index scan in KV and index reader in MilevaDB 356 // will be different. The schemaReplicant of index scan will decode all columns of index but the MilevaDB only need some of them. 357 dataSourceSchema *memex.Schema 358 359 // Hist is the histogram when the query was issued. 360 // It is used for query feedback. 361 Hist *statistics.Histogram 362 363 rangeInfo string 364 365 // The index scan may be on a partition. 366 physicalBlockID int64 367 368 GenExprs map[perceptron.BlockDeferredCausetID]memex.Expression 369 370 isPartition bool 371 Desc bool 372 KeepOrder bool 373 // DoubleRead means if the index interlock will read ekv two times. 374 // If the query requires the columns that don't belong to index, DoubleRead will be true. 375 DoubleRead bool 376 377 NeedCommonHandle bool 378 } 379 380 // Clone implements PhysicalCauset interface. 381 func (p *PhysicalIndexScan) Clone() (PhysicalCauset, error) { 382 cloned := new(PhysicalIndexScan) 383 *cloned = *p 384 base, err := p.physicalSchemaProducer.cloneWithSelf(cloned) 385 if err != nil { 386 return nil, err 387 } 388 cloned.physicalSchemaProducer = *base 389 cloned.AccessCondition = cloneExprs(p.AccessCondition) 390 if p.Block != nil { 391 cloned.Block = p.Block.Clone() 392 } 393 if p.Index != nil { 394 cloned.Index = p.Index.Clone() 395 } 396 cloned.IdxDefCauss = cloneDefCauss(p.IdxDefCauss) 397 cloned.IdxDefCausLens = make([]int, len(p.IdxDefCausLens)) 398 copy(cloned.IdxDefCausLens, p.IdxDefCausLens) 399 cloned.Ranges = cloneRanges(p.Ranges) 400 cloned.DeferredCausets = cloneDefCausInfos(p.DeferredCausets) 401 if p.dataSourceSchema != nil { 402 cloned.dataSourceSchema = p.dataSourceSchema.Clone() 403 } 404 if p.Hist != nil { 405 cloned.Hist = p.Hist.Copy() 406 } 407 return cloned, nil 408 } 409 410 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 411 func (p *PhysicalIndexScan) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 412 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.AccessCondition)) 413 for _, expr := range p.AccessCondition { 414 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 415 } 416 return corDefCauss 417 } 418 419 // PhysicalMemBlock reads memory causet. 420 type PhysicalMemBlock struct { 421 physicalSchemaProducer 422 423 DBName perceptron.CIStr 424 Block *perceptron.BlockInfo 425 DeferredCausets []*perceptron.DeferredCausetInfo 426 Extractor MemBlockPredicateExtractor 427 QueryTimeRange QueryTimeRange 428 } 429 430 // PhysicalBlockScan represents a causet scan plan. 431 type PhysicalBlockScan struct { 432 physicalSchemaProducer 433 434 // AccessCondition is used to calculate range. 435 AccessCondition []memex.Expression 436 filterCondition []memex.Expression 437 438 Block *perceptron.BlockInfo 439 DeferredCausets []*perceptron.DeferredCausetInfo 440 DBName perceptron.CIStr 441 Ranges []*ranger.Range 442 PkDefCauss []*memex.DeferredCauset 443 444 BlockAsName *perceptron.CIStr 445 446 // Hist is the histogram when the query was issued. 447 // It is used for query feedback. 448 Hist *statistics.Histogram 449 450 physicalBlockID int64 451 452 rangeDecidedBy []*memex.DeferredCauset 453 454 // HandleIdx is the index of handle, which is only used for admin check causet. 455 HandleIdx []int 456 HandleDefCauss HandleDefCauss 457 458 StoreType ekv.StoreType 459 460 IsGlobalRead bool 461 462 // The causet scan may be a partition, rather than a real causet. 463 isPartition bool 464 // KeepOrder is true, if sort data by scanning pkcol, 465 KeepOrder bool 466 Desc bool 467 468 isChildOfIndexLookUp bool 469 } 470 471 // Clone implements PhysicalCauset interface. 472 func (ts *PhysicalBlockScan) Clone() (PhysicalCauset, error) { 473 clonedScan := new(PhysicalBlockScan) 474 *clonedScan = *ts 475 prod, err := ts.physicalSchemaProducer.cloneWithSelf(clonedScan) 476 if err != nil { 477 return nil, err 478 } 479 clonedScan.physicalSchemaProducer = *prod 480 clonedScan.AccessCondition = cloneExprs(ts.AccessCondition) 481 clonedScan.filterCondition = cloneExprs(ts.filterCondition) 482 if ts.Block != nil { 483 clonedScan.Block = ts.Block.Clone() 484 } 485 clonedScan.DeferredCausets = cloneDefCausInfos(ts.DeferredCausets) 486 clonedScan.Ranges = cloneRanges(ts.Ranges) 487 clonedScan.PkDefCauss = cloneDefCauss(ts.PkDefCauss) 488 clonedScan.BlockAsName = ts.BlockAsName 489 if ts.Hist != nil { 490 clonedScan.Hist = ts.Hist.Copy() 491 } 492 clonedScan.rangeDecidedBy = cloneDefCauss(ts.rangeDecidedBy) 493 return clonedScan, nil 494 } 495 496 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 497 func (ts *PhysicalBlockScan) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 498 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(ts.AccessCondition)+len(ts.filterCondition)) 499 for _, expr := range ts.AccessCondition { 500 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 501 } 502 for _, expr := range ts.filterCondition { 503 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 504 } 505 return corDefCauss 506 } 507 508 // IsPartition returns true and partition ID if it's actually a partition. 509 func (ts *PhysicalBlockScan) IsPartition() (bool, int64) { 510 return ts.isPartition, ts.physicalBlockID 511 } 512 513 // ExpandVirtualDeferredCauset expands the virtual column's dependent columns to ts's schemaReplicant and column. 514 func ExpandVirtualDeferredCauset(columns []*perceptron.DeferredCausetInfo, schemaReplicant *memex.Schema, 515 defcausInfo []*perceptron.DeferredCausetInfo) []*perceptron.DeferredCausetInfo { 516 copyDeferredCauset := make([]*perceptron.DeferredCausetInfo, len(columns)) 517 copy(copyDeferredCauset, columns) 518 var extraDeferredCauset *memex.DeferredCauset 519 var extraDeferredCausetPerceptron *perceptron.DeferredCausetInfo 520 if schemaReplicant.DeferredCausets[len(schemaReplicant.DeferredCausets)-1].ID == perceptron.ExtraHandleID { 521 extraDeferredCauset = schemaReplicant.DeferredCausets[len(schemaReplicant.DeferredCausets)-1] 522 extraDeferredCausetPerceptron = copyDeferredCauset[len(copyDeferredCauset)-1] 523 schemaReplicant.DeferredCausets = schemaReplicant.DeferredCausets[:len(schemaReplicant.DeferredCausets)-1] 524 copyDeferredCauset = copyDeferredCauset[:len(copyDeferredCauset)-1] 525 } 526 schemaDeferredCausets := schemaReplicant.DeferredCausets 527 for _, col := range schemaDeferredCausets { 528 if col.VirtualExpr == nil { 529 continue 530 } 531 532 baseDefCauss := memex.ExtractDependentDeferredCausets(col.VirtualExpr) 533 for _, baseDefCaus := range baseDefCauss { 534 if !schemaReplicant.Contains(baseDefCaus) { 535 schemaReplicant.DeferredCausets = append(schemaReplicant.DeferredCausets, baseDefCaus) 536 copyDeferredCauset = append(copyDeferredCauset, FindDeferredCausetInfoByID(defcausInfo, baseDefCaus.ID)) 537 } 538 } 539 } 540 if extraDeferredCauset != nil { 541 schemaReplicant.DeferredCausets = append(schemaReplicant.DeferredCausets, extraDeferredCauset) 542 copyDeferredCauset = append(copyDeferredCauset, extraDeferredCausetPerceptron) 543 } 544 return copyDeferredCauset 545 } 546 547 //SetIsChildOfIndexLookUp is to set the bool if is a child of IndexLookUpReader 548 func (ts *PhysicalBlockScan) SetIsChildOfIndexLookUp(isIsChildOfIndexLookUp bool) { 549 ts.isChildOfIndexLookUp = isIsChildOfIndexLookUp 550 } 551 552 // PhysicalProjection is the physical operator of projection. 553 type PhysicalProjection struct { 554 physicalSchemaProducer 555 556 Exprs []memex.Expression 557 CalculateNoDelay bool 558 AvoidDeferredCausetEvaluator bool 559 } 560 561 // Clone implements PhysicalCauset interface. 562 func (p *PhysicalProjection) Clone() (PhysicalCauset, error) { 563 cloned := new(PhysicalProjection) 564 *cloned = *p 565 base, err := p.basePhysicalCauset.cloneWithSelf(cloned) 566 if err != nil { 567 return nil, err 568 } 569 cloned.basePhysicalCauset = *base 570 cloned.Exprs = cloneExprs(p.Exprs) 571 return cloned, err 572 } 573 574 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 575 func (p *PhysicalProjection) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 576 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.Exprs)) 577 for _, expr := range p.Exprs { 578 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 579 } 580 return corDefCauss 581 } 582 583 // PhysicalTopN is the physical operator of topN. 584 type PhysicalTopN struct { 585 basePhysicalCauset 586 587 ByItems []*soliton.ByItems 588 Offset uint64 589 Count uint64 590 } 591 592 // Clone implements PhysicalCauset interface. 593 func (lt *PhysicalTopN) Clone() (PhysicalCauset, error) { 594 cloned := new(PhysicalTopN) 595 *cloned = *lt 596 base, err := lt.basePhysicalCauset.cloneWithSelf(cloned) 597 if err != nil { 598 return nil, err 599 } 600 cloned.basePhysicalCauset = *base 601 cloned.ByItems = make([]*soliton.ByItems, 0, len(lt.ByItems)) 602 for _, it := range lt.ByItems { 603 cloned.ByItems = append(cloned.ByItems, it.Clone()) 604 } 605 return cloned, nil 606 } 607 608 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 609 func (lt *PhysicalTopN) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 610 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(lt.ByItems)) 611 for _, item := range lt.ByItems { 612 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(item.Expr)...) 613 } 614 return corDefCauss 615 } 616 617 // PhysicalApply represents apply plan, only used for subquery. 618 type PhysicalApply struct { 619 PhysicalHashJoin 620 621 CanUseCache bool 622 Concurrency int 623 OuterSchema []*memex.CorrelatedDeferredCauset 624 } 625 626 // Clone implements PhysicalCauset interface. 627 func (la *PhysicalApply) Clone() (PhysicalCauset, error) { 628 cloned := new(PhysicalApply) 629 base, err := la.PhysicalHashJoin.Clone() 630 if err != nil { 631 return nil, err 632 } 633 hj := base.(*PhysicalHashJoin) 634 cloned.PhysicalHashJoin = *hj 635 cloned.CanUseCache = la.CanUseCache 636 cloned.Concurrency = la.Concurrency 637 for _, col := range la.OuterSchema { 638 cloned.OuterSchema = append(cloned.OuterSchema, col.Clone().(*memex.CorrelatedDeferredCauset)) 639 } 640 return cloned, nil 641 } 642 643 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 644 func (la *PhysicalApply) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 645 corDefCauss := la.PhysicalHashJoin.ExtractCorrelatedDefCauss() 646 for i := len(corDefCauss) - 1; i >= 0; i-- { 647 if la.children[0].Schema().Contains(&corDefCauss[i].DeferredCauset) { 648 corDefCauss = append(corDefCauss[:i], corDefCauss[i+1:]...) 649 } 650 } 651 return corDefCauss 652 } 653 654 type basePhysicalJoin struct { 655 physicalSchemaProducer 656 657 JoinType JoinType 658 659 LeftConditions memex.CNFExprs 660 RightConditions memex.CNFExprs 661 OtherConditions memex.CNFExprs 662 663 InnerChildIdx int 664 OuterJoinKeys []*memex.DeferredCauset 665 InnerJoinKeys []*memex.DeferredCauset 666 LeftJoinKeys []*memex.DeferredCauset 667 RightJoinKeys []*memex.DeferredCauset 668 IsNullEQ []bool 669 DefaultValues []types.Causet 670 } 671 672 func (p *basePhysicalJoin) cloneWithSelf(newSelf PhysicalCauset) (*basePhysicalJoin, error) { 673 cloned := new(basePhysicalJoin) 674 base, err := p.physicalSchemaProducer.cloneWithSelf(newSelf) 675 if err != nil { 676 return nil, err 677 } 678 cloned.physicalSchemaProducer = *base 679 cloned.JoinType = p.JoinType 680 cloned.LeftConditions = cloneExprs(p.LeftConditions) 681 cloned.RightConditions = cloneExprs(p.RightConditions) 682 cloned.OtherConditions = cloneExprs(p.OtherConditions) 683 cloned.InnerChildIdx = p.InnerChildIdx 684 cloned.OuterJoinKeys = cloneDefCauss(p.OuterJoinKeys) 685 cloned.InnerJoinKeys = cloneDefCauss(p.InnerJoinKeys) 686 cloned.LeftJoinKeys = cloneDefCauss(p.LeftJoinKeys) 687 cloned.RightJoinKeys = cloneDefCauss(p.RightJoinKeys) 688 for _, d := range p.DefaultValues { 689 cloned.DefaultValues = append(cloned.DefaultValues, *d.Clone()) 690 } 691 return cloned, nil 692 } 693 694 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 695 func (p *basePhysicalJoin) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 696 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.LeftConditions)+len(p.RightConditions)+len(p.OtherConditions)) 697 for _, fun := range p.LeftConditions { 698 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 699 } 700 for _, fun := range p.RightConditions { 701 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 702 } 703 for _, fun := range p.OtherConditions { 704 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 705 } 706 return corDefCauss 707 } 708 709 // PhysicalHashJoin represents hash join implementation of LogicalJoin. 710 type PhysicalHashJoin struct { 711 basePhysicalJoin 712 713 Concurrency uint 714 EqualConditions []*memex.ScalarFunction 715 716 // use the outer causet to build a hash causet when the outer causet is smaller. 717 UseOuterToBuild bool 718 } 719 720 // Clone implements PhysicalCauset interface. 721 func (p *PhysicalHashJoin) Clone() (PhysicalCauset, error) { 722 cloned := new(PhysicalHashJoin) 723 base, err := p.basePhysicalJoin.cloneWithSelf(cloned) 724 if err != nil { 725 return nil, err 726 } 727 cloned.basePhysicalJoin = *base 728 cloned.Concurrency = p.Concurrency 729 cloned.UseOuterToBuild = p.UseOuterToBuild 730 for _, c := range p.EqualConditions { 731 cloned.EqualConditions = append(cloned.EqualConditions, c.Clone().(*memex.ScalarFunction)) 732 } 733 return cloned, nil 734 } 735 736 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 737 func (p *PhysicalHashJoin) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 738 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.EqualConditions)+len(p.LeftConditions)+len(p.RightConditions)+len(p.OtherConditions)) 739 for _, fun := range p.EqualConditions { 740 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 741 } 742 for _, fun := range p.LeftConditions { 743 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 744 } 745 for _, fun := range p.RightConditions { 746 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 747 } 748 for _, fun := range p.OtherConditions { 749 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(fun)...) 750 } 751 return corDefCauss 752 } 753 754 // NewPhysicalHashJoin creates a new PhysicalHashJoin from LogicalJoin. 755 func NewPhysicalHashJoin(p *LogicalJoin, innerIdx int, useOuterToBuild bool, newStats *property.StatsInfo, prop ...*property.PhysicalProperty) *PhysicalHashJoin { 756 leftJoinKeys, rightJoinKeys, isNullEQ, _ := p.GetJoinKeys() 757 baseJoin := basePhysicalJoin{ 758 LeftConditions: p.LeftConditions, 759 RightConditions: p.RightConditions, 760 OtherConditions: p.OtherConditions, 761 LeftJoinKeys: leftJoinKeys, 762 RightJoinKeys: rightJoinKeys, 763 IsNullEQ: isNullEQ, 764 JoinType: p.JoinType, 765 DefaultValues: p.DefaultValues, 766 InnerChildIdx: innerIdx, 767 } 768 hashJoin := PhysicalHashJoin{ 769 basePhysicalJoin: baseJoin, 770 EqualConditions: p.EqualConditions, 771 Concurrency: uint(p.ctx.GetStochastikVars().HashJoinConcurrency()), 772 UseOuterToBuild: useOuterToBuild, 773 }.Init(p.ctx, newStats, p.blockOffset, prop...) 774 return hashJoin 775 } 776 777 // PhysicalIndexJoin represents the plan of index look up join. 778 type PhysicalIndexJoin struct { 779 basePhysicalJoin 780 781 outerSchema *memex.Schema 782 innerTask task 783 784 // Ranges stores the IndexRanges when the inner plan is index scan. 785 Ranges []*ranger.Range 786 // KeyOff2IdxOff maps the offsets in join key to the offsets in the index. 787 KeyOff2IdxOff []int 788 // IdxDefCausLens stores the length of each index column. 789 IdxDefCausLens []int 790 // CompareFilters stores the filters for last column if those filters need to be evaluated during execution. 791 // e.g. select * from t, t1 where t.a = t1.a and t.b > t1.b and t.b < t1.b+10 792 // If there's index(t.a, t.b). All the filters can be used to construct index range but t.b > t1.b and t.b < t1.b=10 793 // need to be evaluated after we fetch the data of t1. 794 // This struct stores them and evaluate them to ranges. 795 CompareFilters *DefCausWithCmpFuncManager 796 } 797 798 // PhysicalIndexMergeJoin represents the plan of index look up merge join. 799 type PhysicalIndexMergeJoin struct { 800 PhysicalIndexJoin 801 802 // KeyOff2KeyOffOrderByIdx maps the offsets in join keys to the offsets in join keys order by index. 803 KeyOff2KeyOffOrderByIdx []int 804 // CompareFuncs causetstore the compare functions for outer join keys and inner join key. 805 CompareFuncs []memex.CompareFunc 806 // OuterCompareFuncs causetstore the compare functions for outer join keys and outer join 807 // keys, it's for outer rows sort's convenience. 808 OuterCompareFuncs []memex.CompareFunc 809 // NeedOuterSort means whether outer rows should be sorted to build range. 810 NeedOuterSort bool 811 // Desc means whether inner child keep desc order. 812 Desc bool 813 } 814 815 // PhysicalIndexHashJoin represents the plan of index look up hash join. 816 type PhysicalIndexHashJoin struct { 817 PhysicalIndexJoin 818 // KeepOuterOrder indicates whether keeping the output result order as the 819 // outer side. 820 KeepOuterOrder bool 821 } 822 823 // PhysicalMergeJoin represents merge join implementation of LogicalJoin. 824 type PhysicalMergeJoin struct { 825 basePhysicalJoin 826 827 CompareFuncs []memex.CompareFunc 828 // Desc means whether inner child keep desc order. 829 Desc bool 830 } 831 832 // PhysicalBroadCastJoin only works for TiFlash Engine, which broadcast the small causet to every replica of probe side of blocks. 833 type PhysicalBroadCastJoin struct { 834 basePhysicalJoin 835 globalChildIndex int 836 } 837 838 // Clone implements PhysicalCauset interface. 839 func (p *PhysicalMergeJoin) Clone() (PhysicalCauset, error) { 840 cloned := new(PhysicalMergeJoin) 841 base, err := p.basePhysicalJoin.cloneWithSelf(cloned) 842 if err != nil { 843 return nil, err 844 } 845 cloned.basePhysicalJoin = *base 846 for _, cf := range p.CompareFuncs { 847 cloned.CompareFuncs = append(cloned.CompareFuncs, cf) 848 } 849 cloned.Desc = p.Desc 850 return cloned, nil 851 } 852 853 // PhysicalLock is the physical operator of dagger, which is used for `select ... for uFIDelate` clause. 854 type PhysicalLock struct { 855 basePhysicalCauset 856 857 Lock *ast.SelectLockInfo 858 859 TblID2Handle map[int64][]HandleDefCauss 860 PartitionedBlock []causet.PartitionedBlock 861 } 862 863 // PhysicalLimit is the physical operator of Limit. 864 type PhysicalLimit struct { 865 basePhysicalCauset 866 867 Offset uint64 868 Count uint64 869 } 870 871 // Clone implements PhysicalCauset interface. 872 func (p *PhysicalLimit) Clone() (PhysicalCauset, error) { 873 cloned := new(PhysicalLimit) 874 *cloned = *p 875 base, err := p.basePhysicalCauset.cloneWithSelf(cloned) 876 if err != nil { 877 return nil, err 878 } 879 cloned.basePhysicalCauset = *base 880 return cloned, nil 881 } 882 883 // PhysicalUnionAll is the physical operator of UnionAll. 884 type PhysicalUnionAll struct { 885 physicalSchemaProducer 886 } 887 888 type basePhysicalAgg struct { 889 physicalSchemaProducer 890 891 AggFuncs []*aggregation.AggFuncDesc 892 GroupByItems []memex.Expression 893 } 894 895 func (p *basePhysicalAgg) cloneWithSelf(newSelf PhysicalCauset) (*basePhysicalAgg, error) { 896 cloned := new(basePhysicalAgg) 897 base, err := p.physicalSchemaProducer.cloneWithSelf(newSelf) 898 if err != nil { 899 return nil, err 900 } 901 cloned.physicalSchemaProducer = *base 902 for _, aggDesc := range p.AggFuncs { 903 cloned.AggFuncs = append(cloned.AggFuncs, aggDesc.Clone()) 904 } 905 cloned.GroupByItems = cloneExprs(p.GroupByItems) 906 return cloned, nil 907 } 908 909 func (p *basePhysicalAgg) numDistinctFunc() (num int) { 910 for _, fun := range p.AggFuncs { 911 if fun.HasDistinct { 912 num++ 913 } 914 } 915 return 916 } 917 918 func (p *basePhysicalAgg) getAggFuncCostFactor() (factor float64) { 919 factor = 0.0 920 for _, agg := range p.AggFuncs { 921 if fac, ok := aggFuncFactor[agg.Name]; ok { 922 factor += fac 923 } else { 924 factor += aggFuncFactor["default"] 925 } 926 } 927 if factor == 0 { 928 factor = 1.0 929 } 930 return 931 } 932 933 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 934 func (p *basePhysicalAgg) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 935 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.GroupByItems)+len(p.AggFuncs)) 936 for _, expr := range p.GroupByItems { 937 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 938 } 939 for _, fun := range p.AggFuncs { 940 for _, arg := range fun.Args { 941 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(arg)...) 942 } 943 } 944 return corDefCauss 945 } 946 947 // PhysicalHashAgg is hash operator of aggregate. 948 type PhysicalHashAgg struct { 949 basePhysicalAgg 950 } 951 952 // Clone implements PhysicalCauset interface. 953 func (p *PhysicalHashAgg) Clone() (PhysicalCauset, error) { 954 cloned := new(PhysicalHashAgg) 955 base, err := p.basePhysicalAgg.cloneWithSelf(cloned) 956 if err != nil { 957 return nil, err 958 } 959 cloned.basePhysicalAgg = *base 960 return cloned, nil 961 } 962 963 // NewPhysicalHashAgg creates a new PhysicalHashAgg from a LogicalAggregation. 964 func NewPhysicalHashAgg(la *LogicalAggregation, newStats *property.StatsInfo, prop *property.PhysicalProperty) *PhysicalHashAgg { 965 agg := basePhysicalAgg{ 966 GroupByItems: la.GroupByItems, 967 AggFuncs: la.AggFuncs, 968 }.initForHash(la.ctx, newStats, la.blockOffset, prop) 969 return agg 970 } 971 972 // PhysicalStreamAgg is stream operator of aggregate. 973 type PhysicalStreamAgg struct { 974 basePhysicalAgg 975 } 976 977 // Clone implements PhysicalCauset interface. 978 func (p *PhysicalStreamAgg) Clone() (PhysicalCauset, error) { 979 cloned := new(PhysicalStreamAgg) 980 base, err := p.basePhysicalAgg.cloneWithSelf(cloned) 981 if err != nil { 982 return nil, err 983 } 984 cloned.basePhysicalAgg = *base 985 return cloned, nil 986 } 987 988 // PhysicalSort is the physical operator of sort, which implements a memory sort. 989 type PhysicalSort struct { 990 basePhysicalCauset 991 992 ByItems []*soliton.ByItems 993 } 994 995 // Clone implements PhysicalCauset interface. 996 func (ls *PhysicalSort) Clone() (PhysicalCauset, error) { 997 cloned := new(PhysicalSort) 998 base, err := ls.basePhysicalCauset.cloneWithSelf(cloned) 999 if err != nil { 1000 return nil, err 1001 } 1002 cloned.basePhysicalCauset = *base 1003 for _, it := range ls.ByItems { 1004 cloned.ByItems = append(cloned.ByItems, it.Clone()) 1005 } 1006 return cloned, nil 1007 } 1008 1009 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 1010 func (ls *PhysicalSort) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 1011 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(ls.ByItems)) 1012 for _, item := range ls.ByItems { 1013 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(item.Expr)...) 1014 } 1015 return corDefCauss 1016 } 1017 1018 // NominalSort asks sort properties for its child. It is a fake operator that will not 1019 // appear in final physical operator tree. It will be eliminated or converted to Projection. 1020 type NominalSort struct { 1021 basePhysicalCauset 1022 1023 // These two fields are used to switch ScalarFunctions to Constants. For these 1024 // NominalSorts, we need to converted to Projections check if the ScalarFunctions 1025 // are out of bounds. (issue #11653) 1026 ByItems []*soliton.ByItems 1027 OnlyDeferredCauset bool 1028 } 1029 1030 // PhysicalUnionScan represents a union scan operator. 1031 type PhysicalUnionScan struct { 1032 basePhysicalCauset 1033 1034 Conditions []memex.Expression 1035 1036 HandleDefCauss HandleDefCauss 1037 } 1038 1039 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 1040 func (p *PhysicalUnionScan) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 1041 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0) 1042 for _, cond := range p.Conditions { 1043 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(cond)...) 1044 } 1045 return corDefCauss 1046 } 1047 1048 // IsPartition returns true and partition ID if it works on a partition. 1049 func (p *PhysicalIndexScan) IsPartition() (bool, int64) { 1050 return p.isPartition, p.physicalBlockID 1051 } 1052 1053 // IsPointGetByUniqueKey checks whether is a point get by unique key. 1054 func (p *PhysicalIndexScan) IsPointGetByUniqueKey(sc *stmtctx.StatementContext) bool { 1055 return len(p.Ranges) == 1 && 1056 p.Index.Unique && 1057 len(p.Ranges[0].LowVal) == len(p.Index.DeferredCausets) && 1058 p.Ranges[0].IsPoint(sc) 1059 } 1060 1061 // PhysicalSelection represents a filter. 1062 type PhysicalSelection struct { 1063 basePhysicalCauset 1064 1065 Conditions []memex.Expression 1066 } 1067 1068 // Clone implements PhysicalCauset interface. 1069 func (p *PhysicalSelection) Clone() (PhysicalCauset, error) { 1070 cloned := new(PhysicalSelection) 1071 base, err := p.basePhysicalCauset.cloneWithSelf(cloned) 1072 if err != nil { 1073 return nil, err 1074 } 1075 cloned.basePhysicalCauset = *base 1076 cloned.Conditions = cloneExprs(p.Conditions) 1077 return cloned, nil 1078 } 1079 1080 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 1081 func (p *PhysicalSelection) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 1082 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.Conditions)) 1083 for _, cond := range p.Conditions { 1084 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(cond)...) 1085 } 1086 return corDefCauss 1087 } 1088 1089 // PhysicalMaxOneRow is the physical operator of maxOneRow. 1090 type PhysicalMaxOneRow struct { 1091 basePhysicalCauset 1092 } 1093 1094 // PhysicalBlockDual is the physical operator of dual. 1095 type PhysicalBlockDual struct { 1096 physicalSchemaProducer 1097 1098 RowCount int 1099 1100 // names is used for OutputNames() method. Dual may be inited when building point get plan. 1101 // So it needs to hold names for itself. 1102 names []*types.FieldName 1103 } 1104 1105 // OutputNames returns the outputting names of each column. 1106 func (p *PhysicalBlockDual) OutputNames() types.NameSlice { 1107 return p.names 1108 } 1109 1110 // SetOutputNames sets the outputting name by the given slice. 1111 func (p *PhysicalBlockDual) SetOutputNames(names types.NameSlice) { 1112 p.names = names 1113 } 1114 1115 // PhysicalWindow is the physical operator of window function. 1116 type PhysicalWindow struct { 1117 physicalSchemaProducer 1118 1119 WindowFuncDescs []*aggregation.WindowFuncDesc 1120 PartitionBy []property.Item 1121 OrderBy []property.Item 1122 Frame *WindowFrame 1123 } 1124 1125 // ExtractCorrelatedDefCauss implements PhysicalCauset interface. 1126 func (p *PhysicalWindow) ExtractCorrelatedDefCauss() []*memex.CorrelatedDeferredCauset { 1127 corDefCauss := make([]*memex.CorrelatedDeferredCauset, 0, len(p.WindowFuncDescs)) 1128 for _, windowFunc := range p.WindowFuncDescs { 1129 for _, arg := range windowFunc.Args { 1130 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(arg)...) 1131 } 1132 } 1133 if p.Frame != nil { 1134 if p.Frame.Start != nil { 1135 for _, expr := range p.Frame.Start.CalcFuncs { 1136 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 1137 } 1138 } 1139 if p.Frame.End != nil { 1140 for _, expr := range p.Frame.End.CalcFuncs { 1141 corDefCauss = append(corDefCauss, memex.ExtractCorDeferredCausets(expr)...) 1142 } 1143 } 1144 } 1145 return corDefCauss 1146 } 1147 1148 // PhysicalShuffle represents a shuffle plan. 1149 // `Tail` and `DataSource` are the last plan within and the first plan following the "shuffle", respectively, 1150 // to build the child interlocks chain. 1151 // Take `Window` operator for example: 1152 // Shuffle -> Window -> Sort -> DataSource, will be separated into: 1153 // ==> Shuffle: for main thread 1154 // ==> Window -> Sort(:Tail) -> shuffleWorker: for workers 1155 // ==> DataSource: for `fetchDataAndSplit` thread 1156 type PhysicalShuffle struct { 1157 basePhysicalCauset 1158 1159 Concurrency int 1160 Tail PhysicalCauset 1161 DataSource PhysicalCauset 1162 1163 SplitterType PartitionSplitterType 1164 HashByItems []memex.Expression 1165 } 1166 1167 // PartitionSplitterType is the type of `Shuffle` interlock splitter, which splits data source into partitions. 1168 type PartitionSplitterType int 1169 1170 const ( 1171 // PartitionHashSplitterType is the splitter splits by hash. 1172 PartitionHashSplitterType = iota 1173 ) 1174 1175 // PhysicalShuffleDataSourceStub represents a data source stub of `PhysicalShuffle`, 1176 // and actually, is executed by `interlock.shuffleWorker`. 1177 type PhysicalShuffleDataSourceStub struct { 1178 physicalSchemaProducer 1179 1180 // Worker points to `interlock.shuffleWorker`. 1181 Worker unsafe.Pointer 1182 } 1183 1184 // DefCauslectCausetStatsVersion uses to collect the statistics version of the plan. 1185 func DefCauslectCausetStatsVersion(plan PhysicalCauset, statsInfos map[string]uint64) map[string]uint64 { 1186 for _, child := range plan.Children() { 1187 statsInfos = DefCauslectCausetStatsVersion(child, statsInfos) 1188 } 1189 switch copCauset := plan.(type) { 1190 case *PhysicalBlockReader: 1191 statsInfos = DefCauslectCausetStatsVersion(copCauset.blockCauset, statsInfos) 1192 case *PhysicalIndexReader: 1193 statsInfos = DefCauslectCausetStatsVersion(copCauset.indexCauset, statsInfos) 1194 case *PhysicalIndexLookUpReader: 1195 // For index loop up, only the indexCauset is necessary, 1196 // because they use the same stats and we do not set the stats info for blockCauset. 1197 statsInfos = DefCauslectCausetStatsVersion(copCauset.indexCauset, statsInfos) 1198 case *PhysicalIndexScan: 1199 statsInfos[copCauset.Block.Name.O] = copCauset.stats.StatsVersion 1200 case *PhysicalBlockScan: 1201 statsInfos[copCauset.Block.Name.O] = copCauset.stats.StatsVersion 1202 } 1203 1204 return statsInfos 1205 } 1206 1207 // PhysicalShow represents a show plan. 1208 type PhysicalShow struct { 1209 physicalSchemaProducer 1210 1211 ShowContents 1212 } 1213 1214 // PhysicalShowDBSJobs is for showing DBS job list. 1215 type PhysicalShowDBSJobs struct { 1216 physicalSchemaProducer 1217 1218 JobNumber int64 1219 } 1220 1221 // BuildMergeJoinCauset builds a PhysicalMergeJoin from the given fields. Currently, it is only used for test purpose. 1222 func BuildMergeJoinCauset(ctx stochastikctx.Context, joinType JoinType, leftKeys, rightKeys []*memex.DeferredCauset) *PhysicalMergeJoin { 1223 baseJoin := basePhysicalJoin{ 1224 JoinType: joinType, 1225 DefaultValues: []types.Causet{types.NewCauset(1), types.NewCauset(1)}, 1226 LeftJoinKeys: leftKeys, 1227 RightJoinKeys: rightKeys, 1228 } 1229 return PhysicalMergeJoin{basePhysicalJoin: baseJoin}.Init(ctx, nil, 0) 1230 } 1231 1232 // SafeClone clones this PhysicalCauset and handles its panic. 1233 func SafeClone(v PhysicalCauset) (_ PhysicalCauset, err error) { 1234 defer func() { 1235 if r := recover(); r != nil { 1236 err = errors.Errorf("%v", r) 1237 } 1238 }() 1239 return v.Clone() 1240 }