Expression Db2ApplyOptimizations(Expression expression, bool searchCondition, bool joinCondition = false) { var expression2 = (new NullComparisonTransformingVisitor_DB2(ParameterValues)).Visit(expression); var binaryExpression = (expression2 is BinaryExpression) ? (expression2 as BinaryExpression) : null; if (_relationalNullsExpandingVisitor == null) { _relationalNullsExpandingVisitor = new RelationalNullsExpandingVisitor(); } if (_predicateReductionExpressionOptimizer == null) { _predicateReductionExpressionOptimizer = new PredicateReductionExpressionOptimizer(); } if (_predicateNegationExpressionOptimizer == null) { _predicateNegationExpressionOptimizer = new PredicateNegationExpressionOptimizer(); } if (_reducingExpressionVisitor == null) { _reducingExpressionVisitor = new ReducingExpressionVisitor(); } if (_booleanExpressionTranslatingVisitor == null) { _booleanExpressionTranslatingVisitor = new BooleanExpressionTranslatingVisitor_DB2(); } expression2 = ((!joinCondition || binaryExpression == null || binaryExpression.NodeType != ExpressionType.Equal) ? Db2ApplyNullSemantics(expression2) : Expression.MakeBinary(binaryExpression.NodeType, Db2ApplyNullSemantics(binaryExpression.Left), Db2ApplyNullSemantics(binaryExpression.Right))); expression2 = _predicateReductionExpressionOptimizer.Visit(expression2); expression2 = _predicateNegationExpressionOptimizer.Visit(expression2); expression2 = _reducingExpressionVisitor.Visit(expression2); if (binaryExpression == null || (expression.NodeType != ExpressionType.Or && expression.NodeType != ExpressionType.And)) { expression2 = _booleanExpressionTranslatingVisitor.Translate(expression2, searchCondition); } return(expression2); }
private Expression ApplyNullSemantics(Expression expression) { var newExpression = new NullComparisonTransformingVisitor(_parametersValues) .Visit(expression); var relationalNullsOptimizedExpandingVisitor = new RelationalNullsOptimizedExpandingVisitor(); var optimizedExpression = relationalNullsOptimizedExpandingVisitor.Visit(newExpression); newExpression = relationalNullsOptimizedExpandingVisitor.IsOptimalExpansion ? optimizedExpression : new RelationalNullsExpandingVisitor().Visit(newExpression); newExpression = new PredicateNegationExpressionOptimizer().Visit(newExpression); newExpression = new ReducingExpressionVisitor().Visit(newExpression); return(newExpression); }
public virtual Expression VisitSelect(SelectExpression selectExpression) { Check.NotNull(selectExpression, nameof(selectExpression)); IDisposable subQueryIndent = null; if (selectExpression.Alias != null) { _sql.AppendLine("("); subQueryIndent = _sql.Indent(); } _sql.Append("SELECT "); if (selectExpression.IsDistinct) { _sql.Append("DISTINCT "); } GenerateTop(selectExpression); if (selectExpression.Projection.Any()) { VisitJoin(selectExpression.Projection); } else if (selectExpression.IsProjectStar) { _sql.Append(DelimitIdentifier(selectExpression.Tables.Single().Alias)) .Append(".*"); } else { _sql.Append("1"); } if (selectExpression.Tables.Any()) { _sql.AppendLine() .Append("FROM "); VisitJoin(selectExpression.Tables, sql => sql.AppendLine()); } if (selectExpression.Predicate != null) { _sql.AppendLine() .Append("WHERE "); var constantExpression = selectExpression.Predicate as ConstantExpression; if (constantExpression != null) { _sql.Append((bool)constantExpression.Value ? "1 = 1" : "1 = 0"); } else { var predicate = new NullComparisonTransformingVisitor(_parameterValues) .Visit(selectExpression.Predicate); // we have to optimize out comparisons to null-valued parameters before we can expand null semantics if (_parameterValues.Count > 0) { var optimizedNullExpansionVisitor = new NullSemanticsOptimizedExpandingVisitor(); var nullSemanticsExpandedOptimized = optimizedNullExpansionVisitor.Visit(predicate); if (optimizedNullExpansionVisitor.OptimizedExpansionPossible) { predicate = nullSemanticsExpandedOptimized; } else { predicate = new NullSemanticsExpandingVisitor() .Visit(predicate); } } predicate = new ReducingExpressionVisitor().Visit(predicate); Visit(predicate); if (selectExpression.Predicate is ParameterExpression || selectExpression.Predicate.IsAliasWithColumnExpression() || selectExpression.Predicate is SelectExpression) { _sql.Append(" = "); _sql.Append(TrueLiteral); } } } if (selectExpression.OrderBy.Any()) { _sql.AppendLine() .Append("ORDER BY "); VisitJoin(selectExpression.OrderBy, t => { var aliasExpression = t.Expression as AliasExpression; if (aliasExpression != null) { if (aliasExpression.Alias != null) { var columnExpression = aliasExpression.TryGetColumnExpression(); if (columnExpression != null) { _sql.Append(DelimitIdentifier(columnExpression.TableAlias)) .Append("."); } _sql.Append(DelimitIdentifier(aliasExpression.Alias)); } else { Visit(aliasExpression.Expression); } } else { Visit(t.Expression); } if (t.OrderingDirection == OrderingDirection.Desc) { _sql.Append(" DESC"); } }); } GenerateLimitOffset(selectExpression); if (subQueryIndent != null) { subQueryIndent.Dispose(); _sql.AppendLine() .Append(")"); if (selectExpression.Alias.Length > 0) { _sql.Append(" AS ") .Append(DelimitIdentifier(selectExpression.Alias)); } } return(selectExpression); }
public virtual Expression VisitSelect(SelectExpression selectExpression) { Check.NotNull(selectExpression, nameof(selectExpression)); IDisposable subQueryIndent = null; if (selectExpression.Alias != null) { _relationalCommandBuilder.AppendLine("("); subQueryIndent = _relationalCommandBuilder.Indent(); } _relationalCommandBuilder.Append("SELECT "); if (selectExpression.IsDistinct) { _relationalCommandBuilder.Append("DISTINCT "); } GenerateTop(selectExpression); var projectionAdded = false; if (selectExpression.IsProjectStar) { _relationalCommandBuilder .Append(_sqlGenerationHelper.DelimitIdentifier(selectExpression.Tables.Single().Alias)) .Append(".*"); projectionAdded = true; } if (selectExpression.Projection.Any()) { if (selectExpression.IsProjectStar) { _relationalCommandBuilder.Append(", "); } VisitJoin(selectExpression.Projection); projectionAdded = true; } if (!projectionAdded) { _relationalCommandBuilder.Append("1"); } if (selectExpression.Tables.Any()) { _relationalCommandBuilder.AppendLine() .Append("FROM "); VisitJoin(selectExpression.Tables, sql => sql.AppendLine()); } if (selectExpression.Predicate != null) { _relationalCommandBuilder.AppendLine() .Append("WHERE "); var constantExpression = selectExpression.Predicate as ConstantExpression; if (constantExpression != null) { _relationalCommandBuilder.Append((bool)constantExpression.Value ? "1 = 1" : "1 = 0"); } else { var predicate = new NullComparisonTransformingVisitor(_parametersValues) .Visit(selectExpression.Predicate); var relationalNullsOptimizedExpandingVisitor = new RelationalNullsOptimizedExpandingVisitor(); var newPredicate = relationalNullsOptimizedExpandingVisitor.Visit(predicate); predicate = relationalNullsOptimizedExpandingVisitor.IsOptimalExpansion ? newPredicate : new RelationalNullsExpandingVisitor().Visit(predicate); predicate = new PredicateNegationExpressionOptimizer().Visit(predicate); predicate = new ReducingExpressionVisitor().Visit(predicate); Visit(predicate); if (selectExpression.Predicate is ParameterExpression || selectExpression.Predicate.IsAliasWithColumnExpression() || selectExpression.Predicate is SelectExpression) { _relationalCommandBuilder.Append(" = "); _relationalCommandBuilder.Append(TrueLiteral); } } } if (selectExpression.OrderBy.Any()) { _relationalCommandBuilder.AppendLine(); GenerateOrderBy(selectExpression.OrderBy); } GenerateLimitOffset(selectExpression); if (subQueryIndent != null) { subQueryIndent.Dispose(); _relationalCommandBuilder.AppendLine() .Append(")"); if (selectExpression.Alias.Length > 0) { _relationalCommandBuilder.Append(" AS ") .Append(_sqlGenerationHelper.DelimitIdentifier(selectExpression.Alias)); } } return(selectExpression); }