Example #1
0
        internal static bool IsNameMapProjection(DbSelectExpression select)
        {
            if (select.From is DbTableExpression)
            {
                return(false);
            }
            DbSelectExpression fromSelect = select.From as DbSelectExpression;

            if (fromSelect == null || select.Columns.Count != fromSelect.Columns.Count)
            {
                return(false);
            }
            ReadOnlyCollection <DbColumnDeclaration> fromColumns = fromSelect.Columns;

            // test that all columns in 'select' are refering to columns in the same position
            // in from.
            for (int i = 0, n = select.Columns.Count; i < n; i++)
            {
                DbColumnExpression col = select.Columns[i].Expression as DbColumnExpression;
                if (col == null || !(col.Name == fromColumns[i].Name))
                {
                    return(false);
                }
            }
            return(true);
        }
Example #2
0
        protected virtual DbColumnAssignment VisitColumnAssignment(DbColumnAssignment ca)
        {
            DbColumnExpression c = (DbColumnExpression)Visit(ca.Column);
            Expression         e = Visit(ca.Expression);

            return(UpdateColumnAssignment(ca, c, e));
        }
Example #3
0
 /// <summary>
 /// Add a sequence of order expressions to an accumulated list, prepending so as
 /// to give precedence to the new expressions over any previous expressions
 /// </summary>
 /// <param name="newOrderings"></param>
 protected void PrependOrderings(IList <DbOrderExpression> newOrderings)
 {
     if (newOrderings != null)
     {
         if (this.gatheredOrderings == null)
         {
             this.gatheredOrderings = new List <DbOrderExpression>();
         }
         for (int i = newOrderings.Count - 1; i >= 0; i--)
         {
             this.gatheredOrderings.Insert(0, newOrderings[i]);
         }
         // trim off obvious duplicates
         HashSet <string> unique = new HashSet <string>();
         for (int i = 0; i < this.gatheredOrderings.Count;)
         {
             DbColumnExpression column = this.gatheredOrderings[i].Expression as DbColumnExpression;
             if (column != null)
             {
                 string hash = column.Alias + ":" + column.Name;
                 if (unique.Contains(hash))
                 {
                     this.gatheredOrderings.RemoveAt(i);
                     // don't increment 'i', just continue
                     continue;
                 }
                 else
                 {
                     unique.Add(hash);
                 }
             }
             i++;
         }
     }
 }
Example #4
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     if (this.oldAliases.Contains(column.Alias))
     {
         return(new DbColumnExpression(column.Type, column.DbType, this.newAlias, column.Name));
     }
     return(column);
 }
Example #5
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     if (!this.columns.ContainsKey(column.Name))
     {
         this.columns.Add(column.Name, column);
     }
     return(column);
 }
Example #6
0
        protected override Expression VisitColumn(DbColumnExpression column)
        {
            DbTableAlias newAlias;

            if (this.map.TryGetValue(column.Alias, out newAlias))
            {
                return(new DbColumnExpression(column.Type, column.DbType, newAlias, column.Name));
            }
            return(column);
        }
        protected override Expression VisitColumn(DbColumnExpression column)
        {
            DbColumnExpression mapped;

            if (this.map.TryGetValue(column, out mapped))
            {
                return(mapped);
            }
            return(column);
        }
Example #8
0
        protected DbColumnAssignment UpdateColumnAssignment(
            DbColumnAssignment ca, DbColumnExpression c, Expression e)
        {
            if (c != ca.Column || e != ca.Expression)
            {
                return(new DbColumnAssignment(c, e));
            }

            return(ca);
        }
        bool SameExpression(Expression a, Expression b)
        {
            if (a == b)
            {
                return(true);
            }
            DbColumnExpression ca = a as DbColumnExpression;
            DbColumnExpression cb = b as DbColumnExpression;

            return(ca != null && cb != null && ca.Alias == cb.Alias && ca.Name == cb.Name);
        }
Example #10
0
 internal static bool IsSimpleProjection(DbSelectExpression select)
 {
     foreach (DbColumnDeclaration decl in select.Columns)
     {
         DbColumnExpression col = decl.Expression as DbColumnExpression;
         if (col == null || decl.Name != col.Name)
         {
             return(false);
         }
     }
     return(true);
 }
Example #11
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     if (column.Alias == this.outerAlias)
     {
         DbNamedValueExpression nv;
         if (!this.map.TryGetValue(column, out nv))
         {
             nv = new DbNamedValueExpression("n" + (iParam++), column.DbType, column);
             this.map.Add(column, nv);
         }
         return(nv);
     }
     return(column);
 }
Example #12
0
 internal bool TryGetValue(DbColumnExpression column, out ParameterExpression dbDataReader, out int ordinal)
 {
     for (Scope s = this; s != null; s = s.outer)
     {
         if (column.Alias == s.Alias && this.nameMap.TryGetValue(column.Name, out ordinal))
         {
             dbDataReader = this.dbDataReader;
             return(true);
         }
     }
     dbDataReader = null;
     ordinal      = 0;
     return(false);
 }
Example #13
0
        protected override Expression VisitColumn(DbColumnExpression column)
        {
            ParameterExpression reader;
            int iOrdinal;

            if (this.scope != null && this.scope.TryGetValue(column, out reader, out iOrdinal))
            {
                return(Expression.Call(this.GetType(), "GetValue", new Type[] { column.Type }, this.provider, reader, Expression.Constant(iOrdinal)));
            }
            else
            {
                System.Diagnostics.Debug.Fail(string.Format("column not in scope: {0}", column));
            }
            return(column);
        }
        protected override Expression VisitColumn(DbColumnExpression column)
        {
            Dictionary <string, Expression> nameMap;

            if (this.map.TryGetValue(column.Alias, out nameMap))
            {
                Expression expr;
                if (nameMap.TryGetValue(column.Name, out expr))
                {
                    return(this.Visit(expr));
                }
                throw new Exception("Reference to undefined column");
            }
            return(column);
        }
Example #15
0
 protected override Expression Visit(Expression expression)
 {
     if (this.candidates.Contains(expression))
     {
         if (expression.NodeType == (ExpressionType)DbExpressionType.Column)
         {
             DbColumnExpression column = (DbColumnExpression)expression;
             DbColumnExpression mapped;
             if (this.map.TryGetValue(column, out mapped))
             {
                 return(mapped);
             }
             // check for column that already refers to this column
             foreach (DbColumnDeclaration existingColumn in this.columns)
             {
                 DbColumnExpression cex = existingColumn.Expression as DbColumnExpression;
                 if (cex != null && cex.Alias == column.Alias && cex.Name == column.Name)
                 {
                     // refer to the column already in the column list
                     return(new DbColumnExpression(column.Type, column.DbType, this.newAlias, existingColumn.Name));
                 }
             }
             if (this.existingAliases.Contains(column.Alias))
             {
                 int    ordinal    = this.columns.Count;
                 string columnName = this.GetUniqueColumnName(column.Name);
                 this.columns.Add(new DbColumnDeclaration(columnName, column));
                 mapped = new DbColumnExpression(column.Type, column.DbType, this.newAlias, columnName);
                 this.map.Add(column, mapped);
                 this.columnNames.Add(columnName);
                 return(mapped);
             }
             // must be referring to outer scope
             return(column);
         }
         else
         {
             string columnName = this.GetNextColumnName();
             this.columns.Add(new DbColumnDeclaration(columnName, expression));
             return(new DbColumnExpression(expression.Type, null, this.newAlias, columnName));
         }
     }
     else
     {
         return(base.Visit(expression));
     }
 }
Example #16
0
        protected override Expression VisitOuterJoined(DbOuterJoinedExpression outer)
        {
            Expression          expr   = this.Visit(outer.Expression);
            DbColumnExpression  column = (DbColumnExpression)outer.Test;
            ParameterExpression reader;
            int iOrdinal;

            if (this.scope.TryGetValue(column, out reader, out iOrdinal))
            {
                return(Expression.Condition(
                           Expression.Call(reader, "IsDbNull", null, Expression.Constant(iOrdinal)),
                           Expression.Constant(outer.Type.CreateInstance(), outer.Type),
                           expr
                           ));
            }
            return(expr);
        }
        private bool GetEquiJoinKeyExpressions(Expression predicate, DbTableAlias outerAlias,
                                               List <Expression> outerExpressions, List <Expression> innerExpressions)
        {
            if (predicate.NodeType == ExpressionType.Equal)
            {
                var b = (BinaryExpression)predicate;
                DbColumnExpression leftCol  = this.GetColumnExpression(b.Left);
                DbColumnExpression rightCol = this.GetColumnExpression(b.Right);
                if (leftCol != null && rightCol != null)
                {
                    if (leftCol.Alias == outerAlias)
                    {
                        outerExpressions.Add(b.Left);
                        innerExpressions.Add(b.Right);
                        return(true);
                    }
                    else if (rightCol.Alias == outerAlias)
                    {
                        innerExpressions.Add(b.Left);
                        outerExpressions.Add(b.Right);
                        return(true);
                    }
                }
            }

            bool hadKey = false;
            var  parts  = predicate.Split(ExpressionType.And, ExpressionType.AndAlso);

            if (parts.Length > 1)
            {
                foreach (var part in parts)
                {
                    bool hasOuterAliasReference = ReferencedAliasGatherer.Gather(part).Contains(outerAlias);
                    if (hasOuterAliasReference)
                    {
                        if (!GetEquiJoinKeyExpressions(part, outerAlias, outerExpressions, innerExpressions))
                        {
                            return(false);
                        }
                        hadKey = true;
                    }
                }
            }

            return(hadKey);
        }
        protected override Expression VisitSelect(DbSelectExpression select)
        {
            select = (DbSelectExpression)base.VisitSelect(select);

            // look for redundant column declarations
            List <DbColumnDeclaration> cols = select.Columns.OrderBy(c => c.Name).ToList();
            BitArray removed    = new BitArray(select.Columns.Count);
            bool     anyRemoved = false;

            for (int i = 0, n = cols.Count; i < n - 1; i++)
            {
                DbColumnDeclaration ci  = cols[i];
                DbColumnExpression  cix = ci.Expression as DbColumnExpression;
                DbDataType          qt  = cix != null ? cix.DbType : null;
                DbColumnExpression  cxi = new DbColumnExpression(ci.Expression.Type, qt, select.Alias, ci.Name);
                for (int j = i + 1; j < n; j++)
                {
                    if (!removed.Get(j))
                    {
                        DbColumnDeclaration cj = cols[j];
                        if (SameExpression(ci.Expression, cj.Expression))
                        {
                            // any reference to 'j' should now just be a reference to 'i'
                            DbColumnExpression cxj = new DbColumnExpression(cj.Expression.Type, qt, select.Alias, cj.Name);
                            this.map.Add(cxj, cxi);
                            removed.Set(j, true);
                            anyRemoved = true;
                        }
                    }
                }
            }
            if (anyRemoved)
            {
                List <DbColumnDeclaration> newDecls = new List <DbColumnDeclaration>();
                for (int i = 0, n = cols.Count; i < n; i++)
                {
                    if (!removed.Get(i))
                    {
                        newDecls.Add(cols[i]);
                    }
                }
                select = select.SetColumns(newDecls);
            }
            return(select);
        }
Example #19
0
        /// <summary>
        /// Rebind order expressions to reference a new alias and add to column declarations if necessary
        /// </summary>
        protected virtual BindResult RebindOrderings(IEnumerable <DbOrderExpression> orderings, DbTableAlias alias,
                                                     HashSet <DbTableAlias> existingAliases, IEnumerable <DbColumnDeclaration> existingColumns)
        {
            List <DbColumnDeclaration> newColumns   = null;
            List <DbOrderExpression>   newOrderings = new List <DbOrderExpression>();

            foreach (DbOrderExpression ordering in orderings)
            {
                Expression         expr   = ordering.Expression;
                DbColumnExpression column = expr as DbColumnExpression;
                if (column == null || (existingAliases != null && existingAliases.Contains(column.Alias)))
                {
                    // check to see if a declared column already contains a similar expression
                    int iOrdinal = 0;
                    foreach (DbColumnDeclaration decl in existingColumns)
                    {
                        DbColumnExpression declColumn = decl.Expression as DbColumnExpression;
                        if (decl.Expression == ordering.Expression ||
                            (column != null && declColumn != null && column.Alias == declColumn.Alias && column.Name == declColumn.Name))
                        {
                            // found it, so make a reference to this column
                            expr = new DbColumnExpression(column.Type, column.DbType, alias, decl.Name);
                            break;
                        }
                        iOrdinal++;
                    }
                    // if not already projected, add a new column declaration for it
                    if (expr == ordering.Expression)
                    {
                        if (newColumns == null)
                        {
                            newColumns      = new List <DbColumnDeclaration>(existingColumns);
                            existingColumns = newColumns;
                        }
                        string colName = column != null ? column.Name : "c" + iOrdinal;
                        newColumns.Add(new DbColumnDeclaration(colName, ordering.Expression));
                        expr = new DbColumnExpression(expr.Type, null, alias, colName);
                    }
                    newOrderings.Add(new DbOrderExpression(ordering.OrderType, expr));
                }
            }
            return(new BindResult(existingColumns, newOrderings));
        }
Example #20
0
        protected override Expression VisitBinary(BinaryExpression b)
        {
            Expression left  = this.Visit(b.Left);
            Expression right = this.Visit(b.Right);

            if (left.NodeType == (ExpressionType)DbExpressionType.NamedValue &&
                right.NodeType == (ExpressionType)DbExpressionType.Column)
            {
                DbNamedValueExpression nv = (DbNamedValueExpression)left;
                DbColumnExpression     c  = (DbColumnExpression)right;
                left = new DbNamedValueExpression(nv.Name, c.DbType, nv.Value);
            }
            else if (b.Right.NodeType == (ExpressionType)DbExpressionType.NamedValue &&
                     b.Left.NodeType == (ExpressionType)DbExpressionType.Column)
            {
                DbNamedValueExpression nv = (DbNamedValueExpression)right;
                DbColumnExpression     c  = (DbColumnExpression)left;
                right = new DbNamedValueExpression(nv.Name, c.DbType, nv.Value);
            }
            return(this.UpdateBinary(b, left, right, b.Conversion, b.IsLiftedToNull, b.Method));
        }
        private Expression MakeSubquery(Expression expression)
        {
            var newAlias = new DbTableAlias();
            var aliases  = DeclaredAliasGatherer.Gather(expression);

            var decls = new List <DbColumnDeclaration>();

            foreach (var ta in aliases)
            {
                foreach (var col in this.columns[ta])
                {
                    string name = decls.GetAvailableColumnName(col.Name);
                    var    decl = new DbColumnDeclaration(name, col);
                    decls.Add(decl);
                    var newCol = new DbColumnExpression(col.Type, col.DbType, newAlias, col.Name);
                    this.map.Add(col, newCol);
                }
            }

            return(new DbSelectExpression(newAlias, decls, expression, null));
        }
Example #22
0
        protected override Expression VisitSelect(DbSelectExpression select)
        {
            select = (DbSelectExpression)base.VisitSelect(select);
            if (select.Skip != null)
            {
                DbSelectExpression newSelect = select.SetSkip(null).SetTake(null);
                bool canAddColumn            = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0);
                if (!canAddColumn)
                {
                    newSelect = newSelect.AddRedundantSelect(new DbTableAlias());
                }
                newSelect = newSelect.AddColumn(new DbColumnDeclaration("rownum", new DbRowNumberExpression(select.OrderBy)));

                // add layer for WHERE clause that references new rownum column
                newSelect = newSelect.AddRedundantSelect(new DbTableAlias());
                newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == "rownum"));

                var newAlias             = ((DbSelectExpression)newSelect.From).Alias;
                DbColumnExpression rnCol = new DbColumnExpression(typeof(int), null, newAlias, "rownum");
                Expression where;
                if (select.Take != null)
                {
                    where = new DbBetweenExpression(rnCol, Expression.Add(select.Skip, Expression.Constant(1)),
                                                    Expression.Add(select.Skip, select.Take));
                }
                else
                {
                    where = rnCol.GreaterThan(select.Skip);
                }
                if (newSelect.Where != null)
                {
                    where = newSelect.Where.And(where);
                }
                newSelect = newSelect.SetWhere(where);

                select = newSelect;
            }
            return(select);
        }
 public DbColumnAssignment(
     DbColumnExpression column, Expression expression)
 {
     _column     = column;
     _expression = expression;
 }
Example #24
0
        private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot)
        {
            bool isAll = method.Name == "All";
            ConstantExpression constSource = source as ConstantExpression;

            if (constSource != null && !IsQuery(constSource))
            {
                System.Diagnostics.Debug.Assert(!isRoot);
                Expression where = null;
                foreach (object value in (IEnumerable)constSource.Value)
                {
                    Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type));
                    if (where == null)
                    {
                        where = expr;
                    }
                    else if (isAll)
                    {
                        where = where.And(expr);
                    }
                    else
                    {
                        where = where.Or(expr);
                    }
                }
                return(this.Visit(where));
            }
            else
            {
                if (isAll)
                {
                    predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray());
                }
                if (predicate != null)
                {
                    source = Expression.Call(typeof(Queryable), "Where", method.GetGenericArguments(), source, predicate);
                }
                DbProjectionExpression projection = this.VisitSequence(source);
                Expression             result     = new DbExistsExpression(projection.Select);
                if (isAll)
                {
                    result = Expression.Not(result);
                }
                if (isRoot)
                {
                    if (this.mapping.Language.AllowSubqueryInSelectWithoutFrom)
                    {
                        return(GetSingletonSequence(result, "SingleOrDefault"));
                    }
                    else
                    {
                        // use count aggregate instead of exists
                        var newSelect = projection.Select.SetColumns(
                            new[] { new DbColumnDeclaration("value", new DbAggregateExpression(typeof(int), DbAggregateType.Count, null, false)) }
                            );
                        var colx = new DbColumnExpression(typeof(int), null, newSelect.Alias, "value");
                        var exp  = isAll
                            ? colx.Equal(Expression.Constant(0))
                            : colx.GreaterThan(Expression.Constant(0));
                        return(new DbProjectionExpression(
                                   newSelect, exp, Aggregator.Aggregate(typeof(bool), typeof(IEnumerable <bool>))
                                   ));
                    }
                }
                return(result);
            }
        }
 protected virtual bool CompareColumn(DbColumnExpression a, DbColumnExpression b)
 {
     return(CompareAlias(a.Alias, b.Alias) && a.Name == b.Name);
 }
Example #26
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     MarkColumnAsUsed(column.Alias, column.Name);
     return(column);
 }
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     this.aliases.Add(column.Alias);
     return(column);
 }
Example #28
0
 protected override Expression VisitColumn(DbColumnExpression column)
 {
     this.columns.Add(column);
     return(column);
 }
Example #29
0
 protected virtual Expression VisitColumn(DbColumnExpression column)
 {
     return(column);
 }