Example #1
0
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            using (Scope())
            {
                var oldOuterMostSelect = outerMostSelect;
                outerMostSelect = proj.Select;

                var oldHasProjectionInProjector = hasProjectionInProjector;
                hasProjectionInProjector = false;

                Expression projector = this.Visit(proj.Projector);
                SelectExpression source = (SelectExpression)this.Visit(proj.Select);

                hasProjectionInProjector = oldHasProjectionInProjector;
                hasProjectionInProjector |= true;

                outerMostSelect = oldOuterMostSelect;
              

                if (source != proj.Select || projector != proj.Projector)
                    return new ProjectionExpression(source, projector, proj.UniqueFunction, proj.Type);

                return proj;
            }

        }
        protected override Expression VisitSelect(SelectExpression select)
        {
            var saveFrom = this.currentFrom;
            var saveInAggregate = this.inAggregate;

            this.inAggregate = false;

            SourceExpression from = this.VisitSource(select.From);
            this.currentFrom = from;

            Expression top = this.Visit(select.Top);
            Expression where = this.Visit(select.Where);
            ReadOnlyCollection<ColumnDeclaration> columns = select.Columns.NewIfChange(VisitColumnDeclaration);
            ReadOnlyCollection<OrderExpression> orderBy = select.OrderBy.NewIfChange(VisitOrderBy);
            ReadOnlyCollection<Expression> groupBy = select.GroupBy.NewIfChange(Visit);

            from = this.currentFrom;

            this.inAggregate = saveInAggregate;
            this.currentFrom = saveFrom;

            if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy)
                return new SelectExpression(select.Alias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions);

            return select;

        }
		protected override Expression VisitSelect(SelectExpression select)
		{
			select = (SelectExpression)base.VisitSelect(select);
			if (lookup.Contains(select.Alias))
			{
				List<ColumnDeclaration> aggColumns = new List<ColumnDeclaration>(select.Columns);
				foreach (AggregateSubqueryExpression ae in lookup[select.Alias])
				{
					string name = "agg" + aggColumns.Count;
					var colType = DbTypeSystem.GetColumnType(ae.Type);
					ColumnDeclaration cd = new ColumnDeclaration(name, ae.AggregateInGroupSelect, colType);
					this.map.Add(ae, new ColumnExpression(ae.Type, colType, ae.GroupByAlias, name));
					aggColumns.Add(cd);
				}
				return new SelectExpression(
					select.Alias,
					aggColumns,
					select.From,
					select.Where,
					select.OrderBy,
					select.GroupBy,
					select.IsDistinct,
					select.Skip,
					select.Take,
					select.IsReverse);
			}
			return select;
		}
 protected override Expression VisitSelect(SelectExpression select)
 {
     TableAlias newAlias = new TableAlias();
     this.map[select.Alias] = newAlias;
     select = (SelectExpression)base.VisitSelect(select);
     return new SelectExpression(newAlias, select.Columns, select.From, select.Where, select.OrderBy, select.GroupBy, select.IsDistinct, select.Skip, select.Take, select.IsReverse);
 }
Example #5
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     Expression saveCurrentFrom = this.currentFrom;
     this.currentFrom = this.VisitSource(select.From);
     try
     {
         Expression where = this.Visit(select.Where);
         ReadOnlyCollection<OrderExpression> orderBy = this.VisitOrderBy(select.OrderBy);
         ReadOnlyCollection<Expression> groupBy = this.VisitExpressionList(select.GroupBy);
         Expression skip = this.Visit(select.Skip);
         Expression take = this.Visit(select.Take);
         ReadOnlyCollection<ColumnDeclaration> columns = this.VisitColumnDeclarations(select.Columns);
         if (this.currentFrom != select.From
             || where != select.Where
             || orderBy != select.OrderBy
             || groupBy != select.GroupBy
             || take != select.Take
             || skip != select.Skip
             || columns != select.Columns
             )
         {
             return new SelectExpression(select.Alias, columns, this.currentFrom, where, orderBy, groupBy, select.IsDistinct, skip, take, select.IsReverse);
         }
         return select;
     }
     finally
     {
         this.currentFrom = saveCurrentFrom;
     }
 }
Example #6
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     if (this.selectsToRemove.Contains(select))
         return this.Visit(select.From);
     else
         return base.VisitSelect(select);
 }
Example #7
0
        protected override Expression VisitIn(InExpression expression)
        {
            if (!ShouldRewrite(expression)) {
                return base.VisitIn(expression);
            }

            Array array = expression.Values.OfType<ConstantExpression>().Select(item => item.Value).Distinct().ToArray();

            var vfpDataXml = new ArrayXmlToCursor(array);
            var tableAlias = new TableAlias();
            var columnType = _language.TypeSystem.GetColumnType(vfpDataXml.ItemType);
            var columnExpression = new ColumnExpression(vfpDataXml.ItemType, columnType, tableAlias, ArrayXmlToCursor.ColumnName);

            var columns = new List<ColumnDeclaration> {
                new ColumnDeclaration(string.Empty, columnExpression, columnType)
            };

            var xml = Expression.Constant(vfpDataXml.Xml);
            var cursorName = Expression.Constant("curTemp_" + DateTime.Now.ToString("ddHHssmm"));
            var check = Expression.GreaterThan(new XmlToCursorExpression(xml, cursorName), Expression.Constant(0));
            var from = Expression.Condition(check, cursorName, Expression.Constant(string.Empty));
            var select = new SelectExpression(tableAlias, columns, from, null);

            return new InExpression(expression.Expression, select);
        }
Example #8
0
        protected internal override Expression VisitSelect(SelectExpression select)
        {
            // visit column projection first
            HashSet<string> columnsUsed = allColumnsUsed.GetOrCreate(select.Alias); // a veces no se usa

            ReadOnlyCollection<ColumnDeclaration> columns = select.Columns.Select(c =>
            {
                if (select.IsDistinct ? IsConstant(c.Expression) : !columnsUsed.Contains(c.Name))
                    return null;

                var ex = Visit(c.Expression);

                return ex == c.Expression ? c : new ColumnDeclaration(c.Name, ex);
            }).NotNull().ToReadOnly();

            ReadOnlyCollection<OrderExpression> orderbys = Visit(select.OrderBy, VisitOrderBy);
            Expression where = this.Visit(select.Where);
            ReadOnlyCollection<Expression> groupBy = select.GroupBy.Select(e => IsConstant(e) ? null : Visit(e)).NotNull().ToReadOnly();

            SourceExpression from = this.VisitSource(select.From);

            if (columns != select.Columns || orderbys != select.OrderBy || where != select.Where || from != select.From || groupBy != select.GroupBy)
                return new SelectExpression(select.Alias, select.IsDistinct, select.Top, columns, from, where, orderbys, groupBy, select.SelectOptions);

            return select;
        }
		public static Expression GetOuterJoinTest(SelectExpression select)
		{
			// if the column is used in the join condition (equality test)
			// if it is null in the database then the join test won't match (null != null) so the row won't appear
			// we can safely use this existing column as our test to determine if the outer join produced a row

			// find a column that is used in equality test
			var aliases = DeclaredAliasGatherer.Gather(select.From);
			var joinColumns = JoinColumnGatherer.Gather(aliases, select).ToList();
			if (joinColumns.Count > 0)
			{
				// prefer one that is already in the projection list.
				foreach (var jc in joinColumns)
				{
					foreach (var col in select.Columns)
					{
						if (jc.Equals(col.Expression))
						{
							return jc;
						}
					}
				}
				return joinColumns[0];
			}

			// fall back to introducing a constant
			return Expression.Constant(1, typeof(int?));
		}
Example #10
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     if (first) {
         first = false;
         return base.VisitSelect(select);
     }
     return select;
 }
Example #11
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     // only consider aggregates in these locations
     this.Visit(select.Where);
     this.VisitOrderBy(select.OrderBy);
     this.VisitColumnDeclarations(select.Columns);
     return select;
 }
Example #12
0
 protected DeclarationCommand UpdateDeclaration(DeclarationCommand decl, IEnumerable<VariableDeclaration> variables, SelectExpression source)
 {
     if (variables != decl.Variables || source != decl.Source)
     {
         return new DeclarationCommand(variables, source);
     }
     return decl;
 }
Example #13
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            bool saveIsOuterMostSelect = this.isOuterMostSelect;
            try
            {
                this.isOuterMostSelect = false;
                select = (SelectExpression)base.VisitSelect(select);

                bool hasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0;
                bool hasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0;
                bool canHaveOrderBy = saveIsOuterMostSelect || select.Take != null || select.Skip != null;
                bool canReceiveOrderings = canHaveOrderBy && !hasGroupBy && !select.IsDistinct;

                if (hasOrderBy)
                {
                    this.PrependOrderings(select.OrderBy);
                }

                IEnumerable<OrderExpression> orderings = null;
                if (canReceiveOrderings)
                {
                    orderings = this.gatheredOrderings;
                }
                else if (canHaveOrderBy)
                {
                    orderings = select.OrderBy;
                }
                bool canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct;
                ReadOnlyCollection<ColumnDeclaration> columns = select.Columns;
                if (this.gatheredOrderings != null)
                {
                    if (canPassOnOrderings)
                    {
                        var producedAliases = DeclaredAliasGatherer.Gather(select.From);
                        // reproject order expressions using this select's alias so the outer select will have properly formed expressions
                        BindResult project = this.RebindOrderings(this.gatheredOrderings, select.Alias, producedAliases, select.Columns);
                        this.gatheredOrderings = null;
                        this.PrependOrderings(project.Orderings);
                        columns = project.Columns;
                    }
                    else
                    {
                        this.gatheredOrderings = null;
                    }
                }
                if (orderings != select.OrderBy || columns != select.Columns)
                {
                    select = new SelectExpression(select.Alias, columns, select.From, select.Where, orderings, select.GroupBy, select.IsDistinct, select.Skip, select.Take);
                }
                return select;
            }
            finally
            {
                this.isOuterMostSelect = saveIsOuterMostSelect;
            }
        }
        public static SelectExpression AddRedundantSelect(this SelectExpression sel, QueryLanguage language, TableAlias newAlias)
        {
            var newColumns =
                from d in sel.Columns
                let qt = (d.Expression is ColumnExpression) ? ((ColumnExpression)d.Expression).QueryType : language.TypeSystem.GetColumnType(d.Expression.Type)
                select new ColumnDeclaration(d.Name, new ColumnExpression(d.Expression.Type, qt, newAlias, d.Name), qt);

            var newFrom = new SelectExpression(newAlias, sel.Columns, sel.From, sel.Where, sel.OrderBy, sel.GroupBy, sel.IsDistinct, sel.Skip, sel.Take, sel.IsReverse);
            return new SelectExpression(sel.Alias, newColumns, newFrom, null, null, null, false, null, null, false);
        }
Example #15
0
 internal static bool IsSimpleProjection(SelectExpression select)
 {
     foreach (ColumnDeclaration decl in select.Columns) {
         ColumnExpression col = decl.Expression as ColumnExpression;
         if (col == null || decl.Name != col.Name) {
             return false;
         }
     }
     return true;
 }
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            SelectExpression save = this.currentSelect;
            this.currentSelect = proj.Source;
            try
            {
                if (!this.isTopLevel)
                {
                    if (this.CanJoinOnClient(this.currentSelect))
                    {
                        // make a query that combines all the constraints from the outer queries into a single select
                        SelectExpression newOuterSelect = (SelectExpression)QueryDuplicator.Duplicate(save);

                        // remap any references to the outer select to the new alias;
                        SelectExpression newInnerSelect = (SelectExpression)ColumnMapper.Map(proj.Source, newOuterSelect.Alias, save.Alias);
                        // add outer-join test
                        ProjectionExpression newInnerProjection = new ProjectionExpression(newInnerSelect, proj.Projector).AddOuterJoinTest();
                        newInnerSelect = newInnerProjection.Source;
                        Expression newProjector = newInnerProjection.Projector;

                        TableAlias newAlias = new TableAlias();
                        var pc = ColumnProjector.ProjectColumns(this.language.CanBeColumn, newProjector, newOuterSelect.Columns, newAlias, newOuterSelect.Alias, newInnerSelect.Alias);
                        JoinExpression join = new JoinExpression(JoinType.OuterApply, newOuterSelect, newInnerSelect, null);
                        SelectExpression joinedSelect = new SelectExpression(newAlias, pc.Columns, join, null, null, null, proj.IsSingleton, null, null);

                        // apply client-join treatment recursively
                        this.currentSelect = joinedSelect;
                        newProjector = this.Visit(pc.Projector); 

                        // compute keys (this only works if join condition was a single column comparison)
                        List<Expression> outerKeys = new List<Expression>();
                        List<Expression> innerKeys = new List<Expression>();
                        if (this.GetEquiJoinKeyExpressions(newInnerSelect.Where, newOuterSelect.Alias, outerKeys, innerKeys))
                        {
                            // outerKey needs to refer to the outer-scope's alias
                            var outerKey = outerKeys.Select(k => ColumnMapper.Map(k, save.Alias, newOuterSelect.Alias));
                            // innerKey needs to refer to the new alias for the select with the new join
                            var innerKey = innerKeys.Select(k => ColumnMapper.Map(k, joinedSelect.Alias, ((ColumnExpression)k).Alias));
                            ProjectionExpression newProjection = new ProjectionExpression(joinedSelect, newProjector, proj.Aggregator);
                            return new ClientJoinExpression(newProjection, outerKey, innerKey);
                        }
                    }
                }
                else
                {
                    this.isTopLevel = false;
                }

                return base.VisitProjection(proj);
            }
            finally 
            {
                this.currentSelect = save;
            }
        }
Example #17
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     var saveColumns = this.columns;
     this.columns = ReferencedColumnGatherer.Gather(select).ToLookup(c => c.Alias);
     var saveLastJoin = this.lastJoin;
     this.lastJoin = null;
     var result = base.VisitSelect(select);
     this.columns = saveColumns;
     this.lastJoin = saveLastJoin;
     return result;
 }
 protected override Expression VisitClientJoin(ClientJoinExpression join)
 {
     // treat client joins as new top level
     var saveTop = isTopLevel;
     var saveSelect = currentSelect;
     isTopLevel = true;
     currentSelect = null;
     Expression result = base.VisitClientJoin(join);
     isTopLevel = saveTop;
     currentSelect = saveSelect;
     return result;
 }
Example #19
0
        private static SelectExpression AddInnerJoins(SelectExpression select, IEnumerable<InExpression> inExpressions)
        {
            foreach (var inExpression in inExpressions) {
                var joinExpression = new JoinExpression(JoinType.InnerJoin,
                                                        select.From,
                                                        inExpression.Select,
                                                        Expression.MakeBinary(ExpressionType.Equal, inExpression.Expression, inExpression.Select.Columns[0].Expression));

                select = select.SetFrom(joinExpression);
            }

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

            // first remove all purely redundant subqueries
            List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(select.From);
            if (redundant != null)
            {
                select = SubqueryRemover.Remove(select, redundant);
            }

            return select;
        }
Example #21
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            Expression from = this.VisitSource(select.From);
            Expression where = this.Visit(select.Where);
            ReadOnlyCollection<OrderExpression> orderBy = this.VisitOrderBy(select.OrderBy);
            ReadOnlyCollection<Expression> groupBy = this.VisitExpressionList(select.GroupBy);
            Expression skip = this.Visit(select.Skip);
            Expression take = this.Visit(select.Take);
            ReadOnlyCollection<ColumnDeclaration> columns = this.VisitColumnDeclarations(select.Columns);

            SelectExpression output = new SelectExpression(select.Alias, columns, from, where, orderBy, groupBy, select.IsDistinct, skip, take);

            return output;
        }
Example #22
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);

            var inExpressions = InExpressionGatherer.Gather(select.Where);

            if (!inExpressions.Any()) {
                return select;
            }

            var newSelect = AddInnerJoins(select, inExpressions);

            return InExpressionRemover.Remove(newSelect, inExpressions);
        }
Example #23
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     var saveWhere = this.currentWhere;
     try {
         this.currentWhere = select.Where;
         var result = (SelectExpression)base.VisitSelect(select);
         if (this.currentWhere != result.Where) {
             return result.SetWhere(this.currentWhere);
         }
         return result;
     }
     finally {
         this.currentWhere = saveWhere;
     }
 }
Example #24
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            Expression top = this.Visit(select.Top);
            SourceExpression from = this.VisitSource(select.From);
            Expression where = this.Visit(select.Where);
            ReadOnlyCollection<ColumnDeclaration> columns = select.Columns.NewIfChange(VisitColumnDeclaration);
            ReadOnlyCollection<OrderExpression> orderBy = select.OrderBy.NewIfChange(VisitOrderBy);
            ReadOnlyCollection<Expression> groupBy = select.GroupBy.NewIfChange(Visit);
            Alias newAlias = aliasMap.TryGetC(select.Alias) ?? select.Alias;

            if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy || newAlias != select.Alias)
                return new SelectExpression(newAlias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions);

            return select;
        }
Example #25
0
 protected internal override Expression VisitSelect(SelectExpression select)
 {
     select = (SelectExpression)base.VisitSelect(select);
     if (lookup.Contains(select.Alias))
     {
         List<ColumnDeclaration> aggColumns = new List<ColumnDeclaration>(select.Columns);
         foreach (AggregateRequestsExpression ae in lookup[select.Alias])
         {
             ColumnDeclaration cd = new ColumnDeclaration("agg" + aggColumns.Count, ae.Aggregate);
             this.map.Add(ae, cd.GetReference(ae.GroupByAlias));
             aggColumns.Add(cd);
         }
         return new SelectExpression(select.Alias, select.IsDistinct, select.Top, aggColumns, select.From, select.Where, select.OrderBy, select.GroupBy, select.SelectOptions);
     }
     return select;
 }
Example #26
0
 internal static bool IsNameMapProjection(SelectExpression select)
 {
     if (select.From is TableExpression) return false;
     SelectExpression fromSelect = select.From as SelectExpression;
     if (fromSelect == null || select.Columns.Count != fromSelect.Columns.Count)
         return false;
     ReadOnlyCollection<ColumnDeclaration> 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++) {
         ColumnExpression col = select.Columns[i].Expression as ColumnExpression;
         if (col == null || !(col.Name == fromColumns[i].Name))
             return false;
     }
     return true;
 }
		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(new TableAlias());
				}

				var colType = DbTypeSystem.GetColumnType(typeof(int));
				newSelect = newSelect.AddColumn(new ColumnDeclaration(columnName, new RowNumberExpression(select.OrderBy), colType));

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

				var newAlias = ((SelectExpression)newSelect.From).Alias;
				ColumnExpression rnCol = new ColumnExpression(typeof(int), colType, newAlias, columnName);
				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;
		}
        private bool TrivialWhere(DeleteExpression delete, SelectExpression select)
        {
            if (delete.Where == null || delete.Where.NodeType == ExpressionType.Equal)
                return false;

            var b = (BinaryExpression)delete.Where;

            var ce1 = b.Left as ColumnExpression;
            var ce2 = b.Right as ColumnExpression;

            if (ce1 == null || ce2 == null)
                return false;

            ce1 = ResolveColumn(ce1, select);
            ce2 = ResolveColumn(ce2, select);

            return ce1.Equals(ce2); 
        }
 /// <summary>
 /// Visits the select.
 /// </summary>
 /// <param name="select">The select.</param>
 /// <returns></returns>
 protected override Expression VisitSelect(SelectExpression select)
 {
     if (select.Skip != null)
     {
         if (select.OrderBy == null && select.OrderBy.Count == 0)
         {
             throw new NotSupportedException("Access cannot support the 'skip' operation without explicit ordering");
         }
         else if (select.Take == null)
         {
             throw new NotSupportedException("Access cannot support the 'skip' operation without the 'take' operation");
         }
         else
         { 
         } 
     }
     return base.VisitSelect(select);
 }
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression) base.VisitSelect(select);

            // look for redundant column declarations
            List<ColumnDeclaration> 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++)
            {
                ColumnDeclaration ci = cols[i];
                ColumnExpression cix = ci.Expression as ColumnExpression;
                QueryType qt = cix != null ? cix.QueryType : ci.QueryType;
                ColumnExpression cxi = new ColumnExpression(ci.Expression.Type, qt, select.Alias, ci.Name);
                for (int j = i + 1; j < n; j++)
                {
                    if (!removed.Get(j))
                    {
                        ColumnDeclaration cj = cols[j];
                        if (SameExpression(ci.Expression, cj.Expression))
                        {
                            // any reference to 'j' should now just be a reference to 'i'
                            ColumnExpression cxj = new ColumnExpression(cj.Expression.Type, qt, select.Alias, cj.Name);
                            this.map.Add(cxj, cxi);
                            removed.Set(j, true);
                            anyRemoved = true;
                        }
                    }
                }
            }
            if (anyRemoved)
            {
                List<ColumnDeclaration> newDecls = new List<ColumnDeclaration>();
                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 #31
0
        protected override Expression VisitSelect(SelectExpression selectExpression)
        {
            if (IsNonComposedSetOperation(selectExpression))
            {
                // Naked set operation
                GenerateSetOperation((SetOperationBase)selectExpression.Tables[0]);

                return(selectExpression);
            }

            IDisposable subQueryIndent = null;

            if (selectExpression.Alias != null)
            {
                _relationalCommandBuilder.AppendLine("(");
                subQueryIndent = _relationalCommandBuilder.Indent();
            }

            _relationalCommandBuilder.Append("SELECT ");

            if (selectExpression.IsDistinct)
            {
                _relationalCommandBuilder.Append("DISTINCT ");
            }

            GenerateTop(selectExpression);

            if (selectExpression.Projection.Any())
            {
                GenerateList(selectExpression.Projection, e => Visit(e));
            }
            else
            {
                _relationalCommandBuilder.Append("1");
            }

            if (selectExpression.Tables.Any())
            {
                _relationalCommandBuilder.AppendLine().Append("FROM ");

                GenerateList(selectExpression.Tables, e => Visit(e), sql => sql.AppendLine());
            }

            if (selectExpression.Predicate != null)
            {
                _relationalCommandBuilder.AppendLine().Append("WHERE ");

                Visit(selectExpression.Predicate);
            }

            if (selectExpression.GroupBy.Count > 0)
            {
                _relationalCommandBuilder.AppendLine().Append("GROUP BY ");

                GenerateList(selectExpression.GroupBy, e => Visit(e));
            }

            if (selectExpression.Having != null)
            {
                _relationalCommandBuilder.AppendLine().Append("HAVING ");

                Visit(selectExpression.Having);
            }

            GenerateOrderings(selectExpression);
            GenerateLimitOffset(selectExpression);

            if (selectExpression.Alias != null)
            {
                subQueryIndent.Dispose();

                _relationalCommandBuilder.AppendLine()
                .Append(")" + AliasSeparator + _sqlGenerationHelper.DelimitIdentifier(selectExpression.Alias));
            }

            return(selectExpression);
        }
Example #32
0
 protected override void GenerateTop([NotNull] SelectExpression selectExpression)
 {
     // No TOP in postgres
 }
 public TestQuerySqlGenerator(
     QuerySqlGeneratorDependencies dependencies,
     SelectExpression selectExpression)
     : base(dependencies, selectExpression)
 {
 }
        protected override Expression VisitSelect(SelectExpression selectExpression)
        {
            var changed = false;
            var parentSearchCondition = _isSearchCondition;

            var projections = new List <ProjectionExpression>();

            _isSearchCondition = false;
            foreach (var item in selectExpression.Projection)
            {
                var updatedProjection = (ProjectionExpression)Visit(item);
                projections.Add(updatedProjection);
                changed |= updatedProjection != item;
            }

            var tables = new List <TableExpressionBase>();

            foreach (var table in selectExpression.Tables)
            {
                var newTable = (TableExpressionBase)Visit(table);
                changed |= newTable != table;
                tables.Add(newTable);
            }

            _isSearchCondition = true;
            var predicate = (SqlExpression)Visit(selectExpression.Predicate);

            changed |= predicate != selectExpression.Predicate;

            var groupBy = new List <SqlExpression>();

            _isSearchCondition = false;
            foreach (var groupingKey in selectExpression.GroupBy)
            {
                var newGroupingKey = (SqlExpression)Visit(groupingKey);
                changed |= newGroupingKey != groupingKey;
                groupBy.Add(newGroupingKey);
            }

            _isSearchCondition = true;
            var havingExpression = (SqlExpression)Visit(selectExpression.Having);

            changed |= havingExpression != selectExpression.Having;

            var orderings = new List <OrderingExpression>();

            _isSearchCondition = false;
            foreach (var ordering in selectExpression.Orderings)
            {
                var orderingExpression = (SqlExpression)Visit(ordering.Expression);
                changed |= orderingExpression != ordering.Expression;
                orderings.Add(ordering.Update(orderingExpression));
            }

            var offset = (SqlExpression)Visit(selectExpression.Offset);

            changed |= offset != selectExpression.Offset;

            var limit = (SqlExpression)Visit(selectExpression.Limit);

            changed |= limit != selectExpression.Limit;

            _isSearchCondition = parentSearchCondition;

            if (changed)
            {
                return(selectExpression.Update(
                           projections, tables, predicate, groupBy, havingExpression, orderings, limit, offset, selectExpression.IsDistinct, selectExpression.Alias));
            }

            return(selectExpression);
        }
 public SelectExpressionCorrelationFindingExpressionVisitor(SelectExpression outerSelectExpression)
 {
     _outerSelectExpression = outerSelectExpression;
 }
Example #36
0
 internal static bool IsInitialProjection(SelectExpression select)
 {
     return(select.From is TableExpression);
 }
Example #37
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = PreProcessSelect(select);

            if (select.From != null)
            {
                VisitSource(select.From);
            }
            if (select.Where != null)
            {
                try
                {
                    //try this first, and if it fails, resort to javascript generation, which is slower on the server side.
                    _queryObject.SetQueryDocument(new BsonDocumentFormatter().FormatDocument(select.Where));
                }
                catch (InvalidQueryException) { throw; }
                catch (Exception)
                {
                    _queryObject.SetWhereClause(new JavascriptFormatter().FormatJavascript(select.Where));
                }
            }

            if (_queryAttributes.IsMapReduce)
            {
                _queryObject.IsMapReduce       = true;
                _queryObject.MapFunction       = new MapReduceMapFunctionBuilder().Build(select.Fields, select.GroupBy);
                _queryObject.ReduceFunction    = new MapReduceReduceFunctionBuilder().Build(select.Fields);
                _queryObject.FinalizerFunction = new MapReduceFinalizerFunctionBuilder().Build(select.Fields);
            }
            else if (!_queryAttributes.IsCount && !select.Fields.HasSelectAllField())
            {
                var fieldGatherer = new FieldGatherer();
                foreach (var field in select.Fields)
                {
                    var expandedFields = fieldGatherer.Gather(field.Expression);
                    foreach (var expandedField in expandedFields)
                    {
                        _queryObject.Fields[expandedField.Name] = 1;
                    }
                }

                // if the _id field isn't selected, then unselect it explicitly
                if (!_queryObject.Fields.Any(e => e.Name.StartsWith("_id")))
                {
                    _queryObject.Fields.Add("_id", 0);
                }
            }

            if (select.OrderBy != null)
            {
                foreach (var order in select.OrderBy)
                {
                    var field = Visit(order.Expression) as FieldExpression;
                    if (field == null)
                    {
                        throw new InvalidQueryException("Complex order by clauses are not supported.");
                    }
                    _queryObject.AddSort(field.Name, order.OrderType == OrderType.Ascending ? 1 : -1);
                }
            }

            if (select.Take != null)
            {
                _queryObject.NumberToLimit = EvaluateConstant <int>(select.Take);
            }

            if (select.Skip != null)
            {
                _queryObject.NumberToSkip = EvaluateConstant <int>(select.Skip);
            }

            return(select);
        }
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public SqliteQuerySqlGenerator(
     [NotNull] QuerySqlGeneratorDependencies dependencies,
     [NotNull] SelectExpression selectExpression)
     : base(dependencies, selectExpression)
 {
 }
        public override JoinQueryResult Visit(SelectExpression exp)
        {
            JoinQueryResult ret = this.Visit(exp);

            return(ret);
        }
Example #40
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     this.AddAliases(select.From);
     this.Write("SELECT ");
     if (select.IsDistinct)
     {
         this.Write("DISTINCT ");
     }
     this.WriteColumns(select.Columns);
     if (select.From != null)
     {
         this.WriteLine(Indentation.Same);
         this.Write("FROM ");
         this.VisitSource(select.From);
     }
     if (select.Where != null)
     {
         this.WriteLine(Indentation.Same);
         this.Write("WHERE ");
         this.VisitPredicate(select.Where);
     }
     if (select.GroupBy != null && select.GroupBy.Count > 0)
     {
         this.WriteLine(Indentation.Same);
         this.Write("GROUP BY ");
         for (int i = 0, n = select.GroupBy.Count; i < n; i++)
         {
             if (i > 0)
             {
                 this.Write(", ");
             }
             this.VisitValue(select.GroupBy[i]);
         }
     }
     if (select.OrderBy != null && select.OrderBy.Count > 0)
     {
         this.WriteLine(Indentation.Same);
         this.Write("ORDER BY ");
         for (int i = 0, n = select.OrderBy.Count; i < n; i++)
         {
             OrderExpression exp = select.OrderBy[i];
             if (i > 0)
             {
                 this.Write(", ");
             }
             this.VisitValue(exp.Expression);
             if (exp.OrderType != OrderType.Ascending)
             {
                 this.Write(" DESC");
             }
         }
     }
     if (select.Take != null)
     {
         this.WriteLine(Indentation.Same);
         this.Write("LIMIT ");
         if (select.Skip == null)
         {
             this.Write("0");
         }
         else
         {
             this.Write(select.Skip);
         }
         this.Write(", ");
         this.Visit(select.Take);
     }
     return(select);
 }
Example #41
0
        /// <summary>
        /// 有跳过的分页
        /// </summary>
        /// <param name="select"></param>
        private void HasSkipPaging(SelectExpression select)
        {
            var externalAlias = this.GetNewAlias();

            _sb.Append("SELECT ");
            var isFromTable = false;

            if (!select.ColumnsPrefix.IsNullOrWhiteSpace())
            {
                _sb.AppendFormat("{0} ", select.ColumnsPrefix);
            }

            int index = 0;

            foreach (var column in select.Columns)
            {
                var tempColumn = column.DeepClone();

                if (index++ > 0)
                {
                    _sb.Append(", ");
                }
                tempColumn.TableAlias = externalAlias;
                this.VisitColumn(tempColumn);
            }

            _sb.Append(" FROM (");
            _sb.Append("SELECT ");

            index = 0;
            if (select.From is TableExpression fromTable)
            {
                isFromTable = true;

                var except = fromTable.Columns.Where(it =>
                                                     select.Columns.Any(x => x.MemberInfo == it.MemberInfo) || select.OrderBy
                                                     .Select(x => x.ColumnExpression).Any(x => x.MemberInfo == it.MemberInfo)).Distinct().ToList();

                foreach (var column in except)
                {
                    if (index++ > 0)
                    {
                        _sb.Append(", ");
                    }
                    column.TableAlias = select.Alias;

                    this.VisitColumn(column);
                }
            }
            else if (select.From is SelectExpression subSelectExpression && subSelectExpression.From is TableExpression fromTable2)
            {
                var except = fromTable2.Columns.Where(it =>
                                                      subSelectExpression.Columns.Any(x => x.MemberInfo == it.MemberInfo) || subSelectExpression.OrderBy
                                                      .Select(x => x.ColumnExpression).Any(x => x.MemberInfo == it.MemberInfo)).Distinct().ToList();

                foreach (var column in except)
                {
                    if (index++ > 0)
                    {
                        _sb.Append(", ");
                    }
                    column.TableAlias = select.Alias;
                    this.VisitColumn(column);
                }
            }
        public void Generates_ignores_missing_take_value()
        {
            var expression = new SelectExpression(typeof(PocoTestType));

            Assert.Null(_generator.GenerateTableQuery(expression).TakeCount);
        }
Example #43
0
 public ExistsExpression Exists(SelectExpression subquery, bool negated)
 {
     return(new ExistsExpression(subquery, negated, _boolTypeMapping));
 }
Example #44
0
 protected virtual void GenerateTop(SelectExpression selectExpression)
 {
 }
 protected override void GenerateTop(SelectExpression expression)
 {
     // not supported in SQLite
 }
Example #46
0
        protected virtual void GenerateSetOperationOperand(SetOperationBase setOperation, SelectExpression operand)
        {
            // INTERSECT has higher precedence over UNION and EXCEPT, but otherwise evaluation is left-to-right.
            // To preserve meaning, add parentheses whenever a set operation is nested within a different set operation.
            if (IsNonComposedSetOperation(operand) &&
                operand.Tables[0].GetType() != setOperation.GetType())
            {
                _relationalCommandBuilder.AppendLine("(");

                using (_relationalCommandBuilder.Indent())
                {
                    Visit(operand);
                }
                _relationalCommandBuilder.AppendLine().Append(")");
            }
            else
            {
                Visit(operand);
            }
        }
Example #47
0
 protected virtual void GenerateTop([NotNull] SelectExpression selectExpression)
 {
     Check.NotNull(selectExpression, nameof(selectExpression));
 }
Example #48
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public override IQuerySqlGenerator CreateDefault(SelectExpression selectExpression)
 => new JetQuerySqlGenerator(
     Dependencies,
     Check.NotNull(selectExpression, nameof(selectExpression)));
 public override ISqlQueryGenerator CreateSqlQueryGenerator(SelectExpression selectExpression) =>
 new SqliteQuerySqlGenerator(selectExpression);
            protected override Expression VisitSelect(SelectExpression select)
            {
                bool wasTopLevel = _isTopLevel;

                _isTopLevel = false;

                select = (SelectExpression)base.VisitSelect(select);

                // next attempt to merge subqueries that would have been removed by the above
                // logic except for the existence of a where clause
                while (CanMergeWithFrom(select, wasTopLevel))
                {
                    SelectExpression fromSelect = GetLeftMostSelect(select.From);

                    // remove the redundant subquery
                    select = SubqueryRemover.Remove(select, fromSelect);

                    // merge where expressions
                    Expression where;
                    Expression having;
                    if (fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0)
                    {
                        where  = fromSelect.Where;
                        having = select.Where;
                        if (fromSelect.Having != null)
                        {
                            having = having != null?Expression.AndAlso(fromSelect.Having, having) : fromSelect.Having;
                        }
                    }
                    else
                    {
                        where = select.Where;
                        if (fromSelect.Where != null)
                        {
                            where = where != null?Expression.AndAlso(fromSelect.Where, where) : fromSelect.Where;
                        }
                        having = null;
                    }

                    var        orderBy = select.OrderBy != null && select.OrderBy.Count > 0 ? select.OrderBy : fromSelect.OrderBy;
                    var        groupBy = select.GroupBy != null && select.GroupBy.Count > 0 ? select.GroupBy : fromSelect.GroupBy;
                    Expression offset  = select.Offset;
                    if (fromSelect.Offset != null)
                    {
                        offset = offset == null ? fromSelect.Offset : Expression.Add(fromSelect.Offset, offset);
                    }
                    Expression limit = select.Limit ?? fromSelect.Limit;
                    if (fromSelect.Limit != null)
                    {
                        limit = limit == null ? fromSelect.Limit :
                                Expression.Call(typeof(Math), nameof(Math.Min), null, fromSelect.Limit, limit);
                    }
                    bool isDistinct = select.IsDistinct | fromSelect.IsDistinct;

                    if (where != select.Where ||
                        orderBy != select.OrderBy ||
                        groupBy != select.GroupBy ||
                        having != select.Having ||
                        isDistinct != select.IsDistinct ||
                        offset != select.Offset ||
                        limit != select.Limit)
                    {
                        select = new SelectExpression(
                            select.Alias, select.Columns, select.From, where, groupBy, having, orderBy, offset, limit, isDistinct
                            );
                    }
                }

                return(select);
            }
Example #51
0
 public override IQuerySqlGenerator CreateDefault(
     SelectExpression selectExpression)
 => new TestQuerySqlGenerator(Dependencies, selectExpression);
Example #52
0
 protected abstract void VisitSelect(SelectExpression expression);
Example #53
0
 protected override void GenerateTop(SelectExpression selectExpression)
 {
 }
Example #54
0
        public override IQueryState Accept(SelectExpression exp)
        {
            ResultElement result = this.CreateNewResult(exp.Selector);

            return(this.CreateQueryState(result));
        }
        protected override Expression VisitSelect(SelectExpression select)
        {
            // visit column projection first
            var columns = select.Columns;

            var wasRetained = _retainAllColumns;

            _retainAllColumns = false;

            List <ColumnDeclaration> alternate = null;

            for (int i = 0, n = select.Columns.Count; i < n; i++)
            {
                var decl = select.Columns[i];
                if (wasRetained || select.IsDistinct || IsColumnUsed(select.Alias, decl.Name))
                {
                    var expr = Visit(decl.Expression);
                    if (expr != decl.Expression)
                    {
                        decl = new ColumnDeclaration(decl.Name, expr);
                    }
                }
                else
                {
                    decl = null;  // null means it gets omitted
                }

                if (decl != select.Columns[i] && alternate == null)
                {
                    alternate = new List <ColumnDeclaration>();
                    for (int j = 0; j < i; j++)
                    {
                        alternate.Add(select.Columns[j]);
                    }
                }

                if (decl != null && alternate != null)
                {
                    alternate.Add(decl);
                }
            }

            if (alternate != null)
            {
                columns = alternate.AsReadOnly();
            }

            var take     = Visit(select.Take);
            var skip     = Visit(select.Skip);
            var groupbys = VisitMemberAndExpressionList(select.GroupBy);
            var orderbys = VisitOrderBy(select.OrderBy);

            var where = Visit(select.Where);
            var having = Visit(select.Having);

            var from = Visit(select.From);

            ClearColumnsUsed(select.Alias);

            //构成新的查询表达式
            select = select.Update(from, where, orderbys, groupbys, skip, take, select.Segment, select.IsDistinct, columns, having, select.IsReverse);

            _retainAllColumns = wasRetained;

            return(select);
        }
 protected override void GenerateTop(SelectExpression selectExpression)
 {
     // Handled by GenerateLimitOffset
 }
Example #57
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     _selects.Add(select);
     return(select);
 }
Example #58
0
 /// <summary>
 ///     Visits the children of the select expression.
 /// </summary>
 /// <param name="selectExpression"> The expression to visit. </param>
 /// <returns> The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. </returns>
 protected abstract Expression VisitSelect([NotNull] SelectExpression selectExpression);
Example #59
0
        public virtual Expression CreateMaterializer(
            [NotNull] IEntityType entityType,
            [NotNull] SelectExpression selectExpression,
            [NotNull] Func <IProperty, SelectExpression, int> projectionAdder,
            [CanBeNull] IQuerySource querySource)
        {
            Check.NotNull(entityType, nameof(entityType));
            Check.NotNull(selectExpression, nameof(selectExpression));
            Check.NotNull(projectionAdder, nameof(projectionAdder));

            var valueBufferParameter
                = Expression.Parameter(typeof(ValueBuffer));

            var concreteEntityTypes
                = entityType.GetConcreteTypesInHierarchy().ToArray();

            var indexMap      = new int[concreteEntityTypes[0].GetProperties().Count()];
            var propertyIndex = 0;

            foreach (var property in concreteEntityTypes[0].GetProperties())
            {
                indexMap[propertyIndex++]
                    = projectionAdder(property, selectExpression);
            }

            var materializer
                = _entityMaterializerSource
                  .CreateMaterializeExpression(
                      concreteEntityTypes[0], valueBufferParameter, indexMap);

            if (concreteEntityTypes.Length == 1 &&
                concreteEntityTypes[0].RootType() == concreteEntityTypes[0])
            {
                return(Expression.Lambda <Func <ValueBuffer, object> >(materializer, valueBufferParameter));
            }

            var discriminatorProperty = _relationalAnnotationProvider.For(concreteEntityTypes[0]).DiscriminatorProperty;

            var discriminatorColumn
                = selectExpression.Projection
                  .OfType <AliasExpression>()
                  .Single(c => c.TryGetColumnExpression()?.Property == discriminatorProperty);

            var firstDiscriminatorValue
                = Expression.Constant(
                      _relationalAnnotationProvider.For(concreteEntityTypes[0]).DiscriminatorValue);

            var discriminatorPredicate
                = Expression.Equal(discriminatorColumn, firstDiscriminatorValue);

            if (concreteEntityTypes.Length == 1)
            {
                selectExpression.Predicate
                    = new DiscriminatorPredicateExpression(discriminatorPredicate, querySource);

                return(Expression.Lambda <Func <ValueBuffer, object> >(materializer, valueBufferParameter));
            }

            var discriminatorValueVariable
                = Expression.Variable(discriminatorProperty.ClrType);

            var returnLabelTarget = Expression.Label(typeof(object));

            var blockExpressions
                = new Expression[]
                {
                Expression.Assign(
                    discriminatorValueVariable,
                    _entityMaterializerSource
                    .CreateReadValueExpression(
                        valueBufferParameter,
                        discriminatorProperty.ClrType,
                        discriminatorProperty.Index)),
                Expression.IfThenElse(
                    Expression.Equal(discriminatorValueVariable, firstDiscriminatorValue),
                    Expression.Return(returnLabelTarget, materializer),
                    Expression.Throw(
                        Expression.Call(
                            _createUnableToDiscriminateException,
                            Expression.Constant(concreteEntityTypes[0])))),
                Expression.Label(
                    returnLabelTarget,
                    Expression.Default(returnLabelTarget.Type))
                };

            foreach (var concreteEntityType in concreteEntityTypes.Skip(1))
            {
                indexMap      = new int[concreteEntityType.GetProperties().Count()];
                propertyIndex = 0;

                foreach (var property in concreteEntityType.GetProperties())
                {
                    indexMap[propertyIndex++]
                        = projectionAdder(property, selectExpression);
                }

                var discriminatorValue
                    = Expression.Constant(
                          _relationalAnnotationProvider.For(concreteEntityType).DiscriminatorValue);

                materializer
                    = _entityMaterializerSource
                      .CreateMaterializeExpression(concreteEntityType, valueBufferParameter, indexMap);

                blockExpressions[1]
                    = Expression.IfThenElse(
                          Expression.Equal(discriminatorValueVariable, discriminatorValue),
                          Expression.Return(returnLabelTarget, materializer),
                          blockExpressions[1]);

                discriminatorPredicate
                    = Expression.OrElse(
                          Expression.Equal(discriminatorColumn, discriminatorValue),
                          discriminatorPredicate);
            }

            selectExpression.Predicate
                = new DiscriminatorPredicateExpression(discriminatorPredicate, querySource);

            return(Expression.Lambda <Func <ValueBuffer, object> >(
                       Expression.Block(new[] { discriminatorValueVariable }, blockExpressions),
                       valueBufferParameter));
        }
Example #60
0
 public LowercaseQuerySqlGenerator(QuerySqlGeneratorDependencies dependencies, RelationalSqlGenerationHelperDependencies rSGenDep, SelectExpression selectExpression) :
     base(
         new QuerySqlGeneratorDependencies(dependencies.CommandBuilderFactory,
                                           new LowercaseSqlGenerationHelper(rSGenDep),
                                           dependencies.ParameterNameGeneratorFactory,
                                           dependencies.RelationalTypeMapper)
         , selectExpression)
 {
 }