code: func extractTableAsNameForUpdate(p LogicalPlan, asNames map[*model.TableInfo][]*model.CIStr) {
  	switch x := p.(type) {
  	case *DataSource:
  		alias := extractTableAlias(p)
  		if alias != nil {
  			if _, ok := asNames[x.tableInfo]; !ok {
  				asNames[x.tableInfo] = make([]*model.CIStr, 0, 1)
  			}
  			asNames[x.tableInfo] = append(asNames[x.tableInfo], alias)
  		}
  	case *LogicalProjection:
  		if !x.calculateGenCols {
  			return
  		}
  
  		ds, isDS := x.Children()[0].(*DataSource)
  		if !isDS {
  			// try to extract the DataSource below a LogicalUnionScan.
  			if us, isUS := x.Children()[0].(*LogicalUnionScan); isUS {
  				ds, isDS = us.Children()[0].(*DataSource)
  			}
  		}
  		if !isDS {
  			return
  		}
  
  		alias := extractTableAlias(x)
  		if alias != nil {
  			if _, ok := asNames[ds.tableInfo]; !ok {
  				asNames[ds.tableInfo] = make([]*model.CIStr, 0, 1)
  			}
  			asNames[ds.tableInfo] = append(asNames[ds.tableInfo], alias)
  		}
  	default:
  		for _, child := range p.Children() {
  			extractTableAsNameForUpdate(child, asNames)
  		}
  	}
  }
docs: // extractTableAsNameForUpdate extracts tables' alias names for update.