Example #1
0
 public static SqlJoinedTable FindJoin(this SelectQuery query,
                                       Func <SqlJoinedTable, bool> match)
 {
     return(QueryVisitor.Find(query, e =>
     {
         if (e.ElementType == QueryElementType.JoinedTable)
         {
             if (match((SqlJoinedTable)e))
             {
                 return true;
             }
         }
         return false;
     }) as SqlJoinedTable);
 }
Example #2
0
        static bool CheckColumn(SelectQuery.Column column, ISqlExpression expr, SelectQuery query, bool optimizeValues, bool optimizeColumns)
        {
            if (expr is SqlField || expr is SelectQuery.Column)
            {
                return(false);
            }

            if (expr is SqlValue)
            {
                return(!optimizeValues && 1.Equals(((SqlValue)expr).Value));
            }

            if (expr is SqlBinaryExpression)
            {
                var e = (SqlBinaryExpression)expr;

                if (e.Operation == "*" && e.Expr1 is SqlValue)
                {
                    var value = (SqlValue)e.Expr1;

                    if (value.Value is int && (int)value.Value == -1)
                    {
                        return(CheckColumn(column, e.Expr2, query, optimizeValues, optimizeColumns));
                    }
                }
            }

            var visitor = new QueryVisitor();

            if (optimizeColumns &&
                QueryVisitor.Find(expr, e => e is SelectQuery || IsAggregationFunction(e)) == null)
            {
                var n = 0;
                var q = query.ParentSelect ?? query;

                visitor.VisitAll(q, e => { if (e == column)
                                           {
                                               n++;
                                           }
                                 });

                return(n > 2);
            }

            return(true);
        }
Example #3
0
        internal void ResolveWeakJoins(List <ISqlTableSource> tables)
        {
            Func <SelectQuery.TableSource, bool> findTable = null; findTable = table =>

            {
                if (tables.Contains(table.Source))
                {
                    return(true);
                }

                foreach (var join in table.Joins)
                {
                    if (findTable(join.Table))
                    {
                        join.IsWeak = false;
                        return(true);
                    }
                }

                if (table.Source is SelectQuery)
                {
                    foreach (var t in ((SelectQuery)table.Source).From.Tables)
                    {
                        if (findTable(t))
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            };

            var areTablesCollected = false;

            _selectQuery.ForEachTable(table =>
            {
                for (var i = 0; i < table.Joins.Count; i++)
                {
                    var join = table.Joins[i];

                    if (join.IsWeak)
                    {
                        if (!areTablesCollected)
                        {
                            areTablesCollected = true;

                            Action <IQueryElement> tableCollector = expr =>
                            {
                                var field = expr as SqlField;

                                if (field != null && !tables.Contains(field.Table))
                                {
                                    tables.Add(field.Table);
                                }
                            };

                            var visitor = new QueryVisitor();

                            visitor.VisitAll(_selectQuery.Select, tableCollector);
                            visitor.VisitAll(_selectQuery.Where, tableCollector);
                            visitor.VisitAll(_selectQuery.GroupBy, tableCollector);
                            visitor.VisitAll(_selectQuery.Having, tableCollector);
                            visitor.VisitAll(_selectQuery.OrderBy, tableCollector);

                            if (_selectQuery.IsInsert)
                            {
                                visitor.VisitAll(_selectQuery.Insert, tableCollector);
                            }

                            if (_selectQuery.IsUpdate)
                            {
                                visitor.VisitAll(_selectQuery.Update, tableCollector);
                            }

                            if (_selectQuery.IsDelete)
                            {
                                visitor.VisitAll(_selectQuery.Delete, tableCollector);
                            }

                            visitor.VisitAll(_selectQuery.From, expr =>
                            {
                                var tbl = expr as SqlTable;

                                if (tbl != null && tbl.TableArguments != null)
                                {
                                    var v = new QueryVisitor();

                                    foreach (var arg in tbl.TableArguments)
                                    {
                                        v.VisitAll(arg, tableCollector);
                                    }
                                }
                            });
                        }

                        if (findTable(join.Table))
                        {
                            join.IsWeak = false;
                        }
                        else
                        {
                            table.Joins.RemoveAt(i);
                            i--;
                        }
                    }
                }
            }, new HashSet <SelectQuery>());
        }
Example #4
0
        void OptimizeUnions()
        {
            var isAllUnion = QueryVisitor.Find(_selectQuery,
                                               ne =>
            {
                var nu = ne as SelectQuery.Union;
                if (nu != null && nu.IsAll == true)
                {
                    return(true);
                }

                return(false);
            });
            var isNotAllUnion = QueryVisitor.Find(_selectQuery,
                                                  ne =>
            {
                var nu = ne as SelectQuery.Union;
                if (nu != null && nu.IsAll == false)
                {
                    return(true);
                }

                return(false);
            });

            if (isNotAllUnion != null && isAllUnion != null)
            {
                return;
            }

            var exprs = new Dictionary <ISqlExpression, ISqlExpression>();

            new QueryVisitor().Visit(_selectQuery, e =>
            {
                var sql = e as SelectQuery;

                if (sql == null || sql.From.Tables.Count != 1 || !sql.IsSimple || sql.IsInsert || sql.IsUpdate || sql.IsDelete)
                {
                    return;
                }

                var table = sql.From.Tables[0];

                if (table.Joins.Count != 0 || !(table.Source is SelectQuery))
                {
                    return;
                }

                var union = (SelectQuery)table.Source;

                if (!union.HasUnion)
                {
                    return;
                }

                for (var i = 0; i < sql.Select.Columns.Count; i++)
                {
                    var scol = sql.Select.Columns[i];
                    var ucol = union.Select.Columns[i];

                    if (scol.Expression != ucol)
                    {
                        return;
                    }
                }

                exprs.Add(union, sql);

                for (var i = 0; i < sql.Select.Columns.Count; i++)
                {
                    var scol = sql.Select.Columns[i];
                    var ucol = union.Select.Columns[i];

                    scol.Expression = ucol.Expression;
                    scol._alias     = ucol._alias;

                    exprs.Add(ucol, scol);
                }

                for (var i = sql.Select.Columns.Count; i < union.Select.Columns.Count; i++)
                {
                    sql.Select.Expr(union.Select.Columns[i].Expression);
                }

                sql.From.Tables.Clear();
                sql.From.Tables.AddRange(union.From.Tables);

                sql.Where.SearchCondition.Conditions.AddRange(union.Where.SearchCondition.Conditions);
                sql.Having.SearchCondition.Conditions.AddRange(union.Having.SearchCondition.Conditions);
                sql.GroupBy.Items.AddRange(union.GroupBy.Items);
                sql.OrderBy.Items.AddRange(union.OrderBy.Items);
                sql.Unions.InsertRange(0, union.Unions);
            });

            ((ISqlExpressionWalkable)_selectQuery).Walk(false, expr =>
            {
                ISqlExpression e;

                if (exprs.TryGetValue(expr, out e))
                {
                    return(e);
                }

                return(expr);
            });
        }
Example #5
0
        public SqlStatement ProcessParameters(MappingSchema mappingSchema)
        {
            if (IsParameterDependent)
            {
                var statement = new QueryVisitor().Convert(this, e =>
                {
                    switch (e.ElementType)
                    {
                    case QueryElementType.SqlParameter:
                        {
                            var p = (SqlParameter)e;

                            if (p.Value == null)
                            {
                                return(new SqlValue(null));
                            }
                        }

                        break;

                    case QueryElementType.ExprExprPredicate:
                        {
                            var ee = (SqlPredicate.ExprExpr)e;

                            if (ee.Operator == SqlPredicate.Operator.Equal || ee.Operator == SqlPredicate.Operator.NotEqual)
                            {
                                object value1;
                                object value2;

                                if (ee.Expr1 is SqlValue v1)
                                {
                                    value1 = v1.Value;
                                }
                                else if (ee.Expr1 is SqlParameter p1)
                                {
                                    value1 = p1.Value;
                                }
                                else
                                {
                                    break;
                                }

                                if (ee.Expr2 is SqlValue v2)
                                {
                                    value2 = v2.Value;
                                }
                                else if (ee.Expr2 is SqlParameter p2)
                                {
                                    value2 = p2.Value;
                                }
                                else
                                {
                                    break;
                                }

                                var value = Equals(value1, value2);

                                if (ee.Operator == SqlPredicate.Operator.NotEqual)
                                {
                                    value = !value;
                                }

                                return(new SqlPredicate.Expr(new SqlValue(value), Precedence.Comparison));
                            }
                        }

                        break;

                    case QueryElementType.InListPredicate:
                        return(ConvertInListPredicate(mappingSchema, (SqlPredicate.InList)e));
                    }

                    return(null);
                });

                if (statement != this)
                {
                    statement.Parameters.Clear();

                    new QueryVisitor().VisitAll(statement, expr =>
                    {
                        switch (expr.ElementType)
                        {
                        case QueryElementType.SqlParameter:
                            {
                                var p = (SqlParameter)expr;
                                if (p.IsQueryParameter)
                                {
                                    statement.Parameters.Add(p);
                                }

                                break;
                            }
                        }
                    });
                }

                return(statement);
            }

            return(this);
        }
Example #6
0
        void OptimizeUnions()
        {
            var isAllUnion = QueryVisitor.Find(_selectQuery,
                                               ne => ne is SqlUnion nu && nu.IsAll);

            var isNotAllUnion = QueryVisitor.Find(_selectQuery,
                                                  ne => ne is SqlUnion nu && !nu.IsAll);

            if (isNotAllUnion != null && isAllUnion != null)
            {
                return;
            }

            var exprs = new Dictionary <ISqlExpression, ISqlExpression>();

            new QueryVisitor().Visit(_selectQuery, e =>
            {
                if (!(e is SelectQuery sql) || sql.From.Tables.Count != 1 || !sql.IsSimple)
                {
                    return;
                }

                var table = sql.From.Tables[0];

                if (table.Joins.Count != 0 || !(table.Source is SelectQuery))
                {
                    return;
                }

                var union = (SelectQuery)table.Source;

                if (!union.HasUnion)
                {
                    return;
                }

                for (var i = 0; i < sql.Select.Columns.Count; i++)
                {
                    var scol = sql.Select.Columns[i];
                    var ucol = union.Select.Columns[i];

                    if (scol.Expression != ucol)
                    {
                        return;
                    }
                }

                exprs.Add(union, sql);

                for (var i = 0; i < sql.Select.Columns.Count; i++)
                {
                    var scol = sql.Select.Columns[i];
                    var ucol = union.Select.Columns[i];

                    scol.Expression = ucol.Expression;
                    scol.RawAlias   = ucol.RawAlias;

                    exprs.Add(ucol, scol);
                }

                for (var i = sql.Select.Columns.Count; i < union.Select.Columns.Count; i++)
                {
                    sql.Select.Expr(union.Select.Columns[i].Expression);
                }

                sql.From.Tables.Clear();
                sql.From.Tables.AddRange(union.From.Tables);

                sql.Where.SearchCondition.Conditions.AddRange(union.Where.SearchCondition.Conditions);
                sql.Having.SearchCondition.Conditions.AddRange(union.Having.SearchCondition.Conditions);
                sql.GroupBy.Items.AddRange(union.GroupBy.Items);
                sql.OrderBy.Items.AddRange(union.OrderBy.Items);
                sql.Unions.InsertRange(0, union.Unions);
            });