code: func (p *LogicalJoin) constructInnerTableScan(ds *DataSource, pk *expression.Column, outerJoinKeys []*expression.Column, us *LogicalUnionScan) PhysicalPlan {
  	ranges := ranger.FullIntRange(mysql.HasUnsignedFlag(pk.RetType.Flag))
  	ts := PhysicalTableScan{
  		Table:           ds.tableInfo,
  		Columns:         ds.Columns,
  		TableAsName:     ds.TableAsName,
  		DBName:          ds.DBName,
  		filterCondition: ds.pushedDownConds,
  		Ranges:          ranges,
  		rangeDecidedBy:  outerJoinKeys,
  	}.Init(ds.ctx)
  	ts.SetSchema(ds.schema)
  
  	ts.stats = property.NewSimpleStats(1)
  	ts.stats.StatsVersion = ds.statisticTable.Version
  	if ds.statisticTable.Pseudo {
  		ts.stats.StatsVersion = statistics.PseudoVersion
  	}
  
  	copTask := &copTask{
  		tablePlan:         ts,
  		indexPlanFinished: true,
  	}
  	selStats := ts.stats.Scale(selectionFactor)
  	ts.addPushedDownSelection(copTask, selStats)
  	t := finishCopTask(ds.ctx, copTask)
  	reader := t.plan()
  	return p.constructInnerUnionScan(us, reader)
  }
docs: // constructInnerTableScan is specially used to construct the inner plan for PhysicalIndexJoin.