func (nr *nameResolver) resolveColumnInTableSources(cn *ast.ColumnNameExpr, tableSources []*ast.TableSource) (done bool) { var matchedResultField *ast.ResultField tableNameL := cn.Name.Table.L columnNameL := cn.Name.Name.L if tableNameL != "" { var matchedTable ast.ResultSetNode for _, ts := range tableSources { if tableNameL == ts.AsName.L { // different table name. matchedTable = ts break } else if ts.AsName.L != "" { // Table as name shadows table real name. continue } if tn, ok := ts.Source.(*ast.TableName); ok { if cn.Name.Schema.L != "" && cn.Name.Schema.L != tn.Schema.L { continue } if tableNameL == tn.Name.L { matchedTable = ts } } } if matchedTable != nil { resultFields := matchedTable.GetResultFields() for _, rf := range resultFields { if rf.ColumnAsName.L == columnNameL || rf.Column.Name.L == columnNameL { // resolve column. matchedResultField = rf break } } } } else { for _, ts := range tableSources { rfs := ts.GetResultFields() for _, rf := range rfs { matchAsName := rf.ColumnAsName.L != "" && rf.ColumnAsName.L == columnNameL matchColumnName := rf.ColumnAsName.L == "" && rf.Column.Name.L == columnNameL if matchAsName || matchColumnName { if matchedResultField != nil { nr.Err = errors.Errorf("column %s is ambiguous.", cn.Name.Name.O) return true } matchedResultField = rf } } } } if matchedResultField != nil { // Bind column. cn.Refer = matchedResultField matchedResultField.Referenced = true return true } return false }
func (nr *nameResolver) resolveColumnInResultFields(ctx *resolverContext, cn *ast.ColumnNameExpr, rfs []*ast.ResultField) bool { var matched *ast.ResultField for _, rf := range rfs { if cn.Name.Table.L != "" { // Check table name if rf.TableAsName.L != "" { if cn.Name.Table.L != rf.TableAsName.L { continue } } else if cn.Name.Table.L != rf.Table.Name.L { continue } } matchAsName := cn.Name.Name.L == rf.ColumnAsName.L var matchColumnName bool if ctx.inHaving { matchColumnName = cn.Name.Name.L == rf.Column.Name.L } else { matchColumnName = rf.ColumnAsName.L == "" && cn.Name.Name.L == rf.Column.Name.L } if matchAsName || matchColumnName { if rf.Column.Name.L == "" { // This is not a real table column, resolve it directly. cn.Refer = rf rf.Referenced = true return true } if matched == nil { matched = rf } else { sameColumn := matched.TableName == rf.TableName && matched.Column.Name.L == rf.Column.Name.L if !sameColumn { nr.Err = errors.Errorf("column %s is ambiguous.", cn.Name.Name.O) return true } } } } if matched != nil { // If in GroupBy, we clone the ResultField if ctx.inGroupBy || ctx.inHaving || ctx.inOrderBy { nf := *matched expr := matched.Expr if cexpr, ok := expr.(*ast.ColumnNameExpr); ok { expr = cexpr.Refer.Expr } nf.Expr = expr matched = &nf } // Bind column. cn.Refer = matched matched.Referenced = true return true } return false }