Example #1
0
        public virtual ProjectionExpression AddOuterJoinTest(ProjectionExpression proj)
        {
            Expression       test    = GetOuterJoinTest(proj.Select);
            SelectExpression select  = proj.Select;
            ColumnExpression testCol = null;

            // look to see if test expression exists in columns already
            foreach (ColumnDeclaration col in select.Columns)
            {
                if (test.Equals(col.Expression))
                {
                    QueryType colType = TypeSystem.GetColumnType(test.Type);
                    testCol = new ColumnExpression(test.Type, colType, select.Alias, col.Name);
                    break;
                }
            }
            if (testCol == null)
            {
                // add expression to projection
                testCol = test as ColumnExpression;
                string colName = (testCol != null) ? testCol.Name : "Test";
                colName = proj.Select.Columns.GetAvailableColumnName(colName);
                QueryType colType = TypeSystem.GetColumnType(test.Type);
                select  = select.AddColumn(new ColumnDeclaration(colName, test, colType));
                testCol = new ColumnExpression(test.Type, colType, select.Alias, colName);
            }
            var newProjector = new OuterJoinedExpression(testCol, proj.Projector);

            return(new ProjectionExpression(select, newProjector, proj.Aggregator));
        }
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);
            if (select.Skip != null)
            {
                SelectExpression newSelect    = select.SetSkip(null).SetTake(null);
                bool             canAddColumn = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0);
                if (!canAddColumn)
                {
                    newSelect = newSelect.AddRedundantSelect(language, new TableAlias());
                }
                QueryType colType = language.TypeSystem.GetColumnType(typeof(int));
                newSelect = newSelect.AddColumn(new ColumnDeclaration("_rownum", new RowNumberExpression(select.OrderBy), colType));

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

                TableAlias newAlias = ((SelectExpression)newSelect.From).Alias;
                var        rnCol    = new ColumnExpression(typeof(int), colType, newAlias, "_rownum");
                Expression where;
                if (select.Take != null)
                {
                    where = new BetweenExpression(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);
        }