internal override SqlSource VisitJoin(SqlJoin join) { join.Left = this.VisitSource(join.Left); join.Right = this.VisitSource(join.Right); join.Condition = this.VisitPredicate(join.Condition); return join; }
internal override SqlExpression VisitMultiset(SqlSubSelect sms) { // allow one big-join per query? if((this.options & SqlMultiplexerOptionType.EnableBigJoin) != 0 && !this.hasBigJoin && this.canJoin && this.isTopLevel && this.outerSelect != null && !MultisetChecker.HasMultiset(sms.Select.Selection) && BigJoinChecker.CanBigJoin(sms.Select)) { sms.Select = this.VisitSelect(sms.Select); SqlAlias alias = new SqlAlias(sms.Select); SqlJoin join = new SqlJoin(SqlJoinType.OuterApply, this.outerSelect.From, alias, null, sms.SourceExpression); this.outerSelect.From = @join; this.outerSelect.OrderingType = SqlOrderingType.Always; // make joined expression SqlExpression expr = (SqlExpression)SqlDuplicator.Copy(sms.Select.Selection); // make count expression SqlSelect copySelect = (SqlSelect)SqlDuplicator.Copy(sms.Select); SqlAlias copyAlias = new SqlAlias(copySelect); SqlSelect countSelect = new SqlSelect(sql.Unary(SqlNodeType.Count, null, sms.SourceExpression), copyAlias, sms.SourceExpression); countSelect.OrderingType = SqlOrderingType.Never; SqlExpression count = sql.SubSelect(SqlNodeType.ScalarSubSelect, countSelect); // make joined collection SqlJoinedCollection jc = new SqlJoinedCollection(sms.ClrType, sms.SqlType, expr, count, sms.SourceExpression); this.hasBigJoin = true; return jc; } return QueryExtractor.Extract(sms, this.parentParameters); }
internal override SqlSource VisitJoin(SqlJoin join) { // block where clauses from being lifted out of the cardinality-dependent // side of an outer join. Scope save = this.current; try { switch(@join.JoinType) { case SqlJoinType.Cross: case SqlJoinType.CrossApply: case SqlJoinType.Inner: return base.VisitJoin(@join); case SqlJoinType.LeftOuter: case SqlJoinType.OuterApply: { @join.Left = this.VisitSource(@join.Left); this.current = null; @join.Right = this.VisitSource(@join.Right); @join.Condition = this.VisitExpression(@join.Condition); return @join; } default: this.current = null; return base.VisitJoin(@join); } } finally { this.current = save; } }
internal override SqlSource VisitJoin(SqlJoin join) { SqlScope save = this.CurrentScope; switch(join.JoinType) { case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: { this.Visit(join.Left); SqlScope tmp = new SqlScope(join.Left, this.CurrentScope.ContainingScope); this.CurrentScope = new SqlScope(null, tmp); this.Visit(join.Right); SqlScope tmp2 = new SqlScope(join.Right, tmp); this.CurrentScope = new SqlScope(null, tmp2); this.Visit(join.Condition); break; } default: { this.Visit(join.Left); this.Visit(join.Right); this.CurrentScope = new SqlScope(null, new SqlScope(join.Right, new SqlScope(join.Left, this.CurrentScope.ContainingScope))); this.Visit(join.Condition); break; } } this.CurrentScope = save; return join; }
internal override SqlSource VisitJoin(SqlJoin join) { base.VisitJoin(@join); if(@join.Condition != null) { this.CheckJoinCondition(@join.Condition); } return @join; }
internal override SqlSource VisitJoin(SqlJoin join) { this.Visit(@join.Left); List<SqlOrderExpression> leftOrders = this.orders; this.orders = null; this.Visit(@join.Right); this.PrependOrderExpressions(leftOrders); 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 CompatibilityAnnotation(Strings.SourceExpressionAnnotation(join.SourceExpression), _providerModesWithIncompatibilities)); // 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); }
internal override SqlSource VisitJoin(SqlJoin join) { switch(join.JoinType) { case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: { this.Visit(join.Left); if(this.found == null) { this.Visit(join.Right); } break; } default: { this.Visit(join.Left); this.Visit(join.Right); break; } } return join; }
internal override SqlSource VisitJoin(SqlJoin join) { base.VisitJoin(@join); switch(@join.JoinType) { case SqlJoinType.Cross: case SqlJoinType.Inner: // reducing either side would effect cardinality of results break; case SqlJoinType.LeftOuter: case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: // may reduce to left if no references to the right if(this.HasEmptySource(@join.Right)) { SqlAlias a = (SqlAlias)@join.Right; _removedMap[a] = a; return @join.Left; } break; } return @join; }
internal override SqlSource VisitJoin(SqlJoin join) { @join.Condition = this.VisitExpression(@join.Condition); @join.Right = this.VisitSource(@join.Right); @join.Left = this.VisitSource(@join.Left); return @join; }
internal override SqlSource VisitJoin(SqlJoin join) { if(join.JoinType == SqlJoinType.CrossApply) { // Visit the left side as usual. join.Left = this.VisitSource(join.Left); // Visit the condition as usual. join.Condition = this.VisitExpression(join.Condition); // Visit the right, with the expressionSink set. SelectScope s = expressionSink; expressionSink = new SelectScope(); expressionSink.LeftProduction = SqlGatherProducedAliases.Gather(join.Left); join.Right = this.VisitSource(join.Right); // Were liftable expressions found? SqlSource newSource = join; foreach(List<SqlColumn> cols in expressionSink.Lifted) { newSource = PushSourceDown(newSource, cols); } expressionSink = s; return newSource; } return base.VisitJoin(join); }
internal virtual SqlSource VisitJoin(SqlJoin join) { join.Left = this.VisitSource(join.Left); join.Right = this.VisitSource(join.Right); join.Condition = this.VisitExpression(join.Condition); return join; }
private SqlSelect VisitDefaultIfEmpty(Expression sequence) { SqlSelect select = this.VisitSequence(sequence); SqlAlias alias = new SqlAlias(select); SqlAliasRef aliasRef = new SqlAliasRef(alias); SqlExpression opt = new SqlOptionalValue( new SqlColumn( "test", _nodeFactory.Unary(SqlNodeType.OuterJoinedValue, _nodeFactory.Value(typeof(int?), _typeProvider.From(typeof(int)), 1, false, _dominatingExpression) ) ), _nodeFactory.Unary(SqlNodeType.OuterJoinedValue, aliasRef) ); SqlSelect optSelect = new SqlSelect(opt, alias, _dominatingExpression); alias = new SqlAlias(optSelect); aliasRef = new SqlAliasRef(alias); SqlExpression litNull = _nodeFactory.TypedLiteralNull(typeof(string), _dominatingExpression); SqlSelect selNull = new SqlSelect(litNull, null, _dominatingExpression); SqlAlias aliasNull = new SqlAlias(selNull); SqlJoin join = new SqlJoin(SqlJoinType.OuterApply, aliasNull, alias, null, _dominatingExpression); return new SqlSelect(aliasRef, join, _dominatingExpression); }
private SqlSelect VisitJoin(Expression outerSequence, Expression innerSequence, LambdaExpression outerKeySelector, LambdaExpression innerKeySelector, LambdaExpression resultSelector) { SqlSelect outerSelect = this.VisitSequence(outerSequence); SqlSelect innerSelect = this.VisitSequence(innerSequence); SqlAlias outerAlias = new SqlAlias(outerSelect); SqlAliasRef outerRef = new SqlAliasRef(outerAlias); SqlAlias innerAlias = new SqlAlias(innerSelect); SqlAliasRef innerRef = new SqlAliasRef(innerAlias); _parameterExpressionToSqlExpression[outerKeySelector.Parameters[0]] = outerRef; SqlExpression outerKey = this.VisitExpression(outerKeySelector.Body); _parameterExpressionToSqlExpression[innerKeySelector.Parameters[0]] = innerRef; SqlExpression innerKey = this.VisitExpression(innerKeySelector.Body); _parameterExpressionToSqlExpression[resultSelector.Parameters[0]] = outerRef; _parameterExpressionToSqlExpression[resultSelector.Parameters[1]] = innerRef; SqlExpression result = this.VisitExpression(resultSelector.Body); SqlExpression condition = _nodeFactory.Binary(SqlNodeType.EQ, outerKey, innerKey); SqlSelect select = null; if((_converterStrategy & ConverterStrategy.CanUseJoinOn) != 0) { SqlJoin join = new SqlJoin(SqlJoinType.Inner, outerAlias, innerAlias, condition, _dominatingExpression); select = new SqlSelect(result, join, _dominatingExpression); } else { SqlJoin join = new SqlJoin(SqlJoinType.Cross, outerAlias, innerAlias, null, _dominatingExpression); select = new SqlSelect(result, join, _dominatingExpression); select.Where = condition; } return select; }
private SqlSelect VisitSelectMany(Expression sequence, LambdaExpression colSelector, LambdaExpression resultSelector) { SqlSelect seqSelect = this.VisitSequence(sequence); SqlAlias seqAlias = new SqlAlias(seqSelect); SqlAliasRef seqRef = new SqlAliasRef(seqAlias); _parameterExpressionToSqlExpression[colSelector.Parameters[0]] = seqRef; SqlNode colSelectorNode = this.VisitSequence(colSelector.Body); SqlAlias selAlias = new SqlAlias(colSelectorNode); SqlAliasRef selRef = new SqlAliasRef(selAlias); SqlJoin join = new SqlJoin(SqlJoinType.CrossApply, seqAlias, selAlias, null, _dominatingExpression); SqlExpression projection = selRef; if(resultSelector != null) { _parameterExpressionToSqlExpression[resultSelector.Parameters[0]] = seqRef; _parameterExpressionToSqlExpression[resultSelector.Parameters[1]] = selRef; projection = this.VisitExpression(resultSelector.Body); } return new SqlSelect(projection, join, _dominatingExpression); }
private SqlSelect VisitSelect(Expression sequence, LambdaExpression selector) { SqlSelect source = this.VisitSequence(sequence); SqlAlias alias = new SqlAlias(source); SqlAliasRef aref = new SqlAliasRef(alias); _parameterExpressionToSqlExpression[selector.Parameters[0]] = aref; SqlNode project = this.Visit(selector.Body); SqlSelect pselect = project as SqlSelect; if(pselect != null) { return new SqlSelect(_nodeFactory.SubSelect(SqlNodeType.Multiset, pselect, selector.Body.Type), alias, _dominatingExpression); } else if((project.NodeType == SqlNodeType.Element || project.NodeType == SqlNodeType.ScalarSubSelect) && (_converterStrategy & ConverterStrategy.CanUseOuterApply) != 0) { SqlSubSelect sub = (SqlSubSelect)project; SqlSelect inner = sub.Select; SqlAlias innerAlias = new SqlAlias(inner); SqlAliasRef innerRef = new SqlAliasRef(innerAlias); if(project.NodeType == SqlNodeType.Element) { inner.Selection = new SqlOptionalValue( new SqlColumn( "test", _nodeFactory.Unary( SqlNodeType.OuterJoinedValue, _nodeFactory.Value(typeof(int?), _typeProvider.From(typeof(int)), 1, false, _dominatingExpression) ) ), _nodeFactory.Unary(SqlNodeType.OuterJoinedValue, inner.Selection) ); } else { inner.Selection = _nodeFactory.Unary(SqlNodeType.OuterJoinedValue, inner.Selection); } SqlJoin join = new SqlJoin(SqlJoinType.OuterApply, alias, innerAlias, null, _dominatingExpression); return new SqlSelect(innerRef, join, _dominatingExpression); } else { SqlExpression expr = project as SqlExpression; if(expr != null) { return new SqlSelect(expr, alias, _dominatingExpression); } else { throw Error.BadProjectionInSelect(); } } }
internal override SqlSource VisitJoin(SqlJoin join) { SqlSource left = this.VisitSource(@join.Left); SqlSource right = this.VisitSource(@join.Right); SqlExpression cond = (SqlExpression)this.Visit(@join.Condition); return new SqlJoin(@join.JoinType, left, right, cond, @join.SourceExpression); }
internal override SqlSource VisitJoin(SqlJoin join) { if (@join.JoinType == SqlJoinType.CrossApply || @join.JoinType == SqlJoinType.OuterApply) { @join.Left = this.VisitSource(@join.Left); SqlSelect saveSelect = this.currentSelect; try { this.currentSelect = this.GetSourceSelect(@join.Left); @join.Right = this.VisitSource(@join.Right); this.currentSelect = null; @join.Condition = this.VisitExpression(@join.Condition); return @join; } finally { this.currentSelect = saveSelect; } } else { return base.VisitJoin(@join); } }
internal override SqlSource VisitJoin(SqlJoin join) { this.ReferenceColumns(@join.Condition); return base.VisitJoin(@join); }
internal override SqlSource VisitJoin(SqlJoin join) { this.Visit(@join.Left); this.NewLine(); switch(@join.JoinType) { case SqlJoinType.CrossApply: _commandStringBuilder.Append("CROSS APPLY "); break; case SqlJoinType.Cross: _commandStringBuilder.Append("CROSS JOIN "); break; case SqlJoinType.Inner: _commandStringBuilder.Append("INNER JOIN "); break; case SqlJoinType.LeftOuter: _commandStringBuilder.Append("LEFT OUTER JOIN "); break; case SqlJoinType.OuterApply: _commandStringBuilder.Append("OUTER APPLY "); break; } SqlJoin rightJoin = @join.Right as SqlJoin; if(rightJoin == null || (rightJoin.JoinType == SqlJoinType.Cross && @join.JoinType != SqlJoinType.CrossApply && @join.JoinType != SqlJoinType.OuterApply)) { this.Visit(@join.Right); } else { this.VisitJoinSource(@join.Right); } if(@join.Condition != null) { _commandStringBuilder.Append(" ON "); this.Visit(@join.Condition); } else if(this.RequiresOnCondition(@join.JoinType)) { _commandStringBuilder.Append(" ON 1=1 "); } return @join; }