private SqlJoin GetLeftOuterWithUnreferencedSingletonOnLeft(SqlSource source) { SqlAlias alias = source as SqlAlias; if (alias != null) { SqlSelect select = alias.Node as SqlSelect; if (select != null && select.Where == null && select.Top == null && select.GroupBy.Count == 0 && select.OrderBy.Count == 0) { return(this.GetLeftOuterWithUnreferencedSingletonOnLeft(select.From)); } } SqlJoin join = source as SqlJoin; if (join == null || join.JoinType != SqlJoinType.LeftOuter) { return(null); } if (!this.IsSingletonSelect(join.Left)) { return(null); } HashSet <SqlAlias> p = SqlGatherProducedAliases.Gather(join.Left); HashSet <SqlAlias> c = SqlGatherConsumedAliases.Gather(join.Right); if (p.Overlaps(c)) { return(null); } return(join); }
internal override SqlSource VisitJoin(SqlJoin join) { if (join.JoinType == SqlJoinType.CrossApply) { // Look down the left side to see what table aliases are produced. HashSet <SqlAlias> p = SqlGatherProducedAliases.Gather(join.Left); // Look down the right side to see what table aliases are consumed. HashSet <SqlAlias> c = SqlGatherConsumedAliases.Gather(join.Right); // Look at each consumed alias and see if they are mentioned in produced. if (p.Overlaps(c)) { Annotations.Add(join, new SqlServerCompatibilityAnnotation(Strings.SourceExpressionAnnotation(join.SourceExpression), SqlProvider.ProviderMode.Sql2000)); // Can't reduce because this consumed alias is produced on the left. return(base.VisitJoin(join)); } // Can turn this into a CROSS JOIN join.JoinType = SqlJoinType.Cross; return(VisitJoin(join)); } return(base.VisitJoin(join)); }