private Expression FindSimilarRight(JoinExpression join, JoinExpression compareTo)
		{
			if (join == null)
			{
				return null;
			}
			if (join.Join == compareTo.Join)
			{
				if (join.Right.NodeType == compareTo.Right.NodeType && DbExpressionComparer.AreEqual(join.Right, compareTo.Right))
				{
					if (join.Condition == compareTo.Condition)
					{
						return join.Right;
					}
					var scope = new ScopedDictionary<TableAlias, TableAlias>(null);
					scope.Add(((AliasedExpression)join.Right).Alias, ((AliasedExpression)compareTo.Right).Alias);
					if (DbExpressionComparer.AreEqual(null, scope, join.Condition, compareTo.Condition))
					{
						return join.Right;
					}
				}
			}
			Expression result = FindSimilarRight(join.Left as JoinExpression, compareTo);
			if (result == null)
			{
				result = FindSimilarRight(join.Right as JoinExpression, compareTo);
			}
			return result;
		}
Example #2
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     if (join.Join == JoinType.SingletonLeftOuter)
     {
         // first visit right side w/o looking at condition
         Expression right = this.Visit(join.Right);
         AliasedExpression ax = right as AliasedExpression;
         if (ax != null && !this.allColumnsUsed.ContainsKey(ax.Alias))
         {
             // if nothing references the alias on the right, then the join is redundant
             return this.Visit(join.Left);
         }
         // otherwise do it the right way
         Expression cond = this.Visit(join.Condition);
         Expression left = this.Visit(join.Left);
         right = this.Visit(join.Right);
         return this.UpdateJoin(join, join.Join, left, right, cond);
     }
     else
     {
         // visit join in reverse order
         Expression condition = this.Visit(join.Condition);
         Expression right = this.VisitSource(join.Right);
         Expression left = this.VisitSource(join.Left);
         return this.UpdateJoin(join, join.Join, left, right, condition);
     }
 }
Example #3
0
        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            Expression source = this.Visit(m.Expression);
            EntityExpression ex = source as EntityExpression;
            IMemberMapping mm = null;

            if (ex != null && (mm = ex.Entity.Get(m.Member)) != null && mm.IsRelationship)
            {
                ProjectionExpression projection = (ProjectionExpression)this.Visit(this.expressionBuilder.GetMemberExpression(source, ex.Entity, m.Member));
                if (this.currentFrom != null && mm.IsManyToOne)
                {
                    // convert singleton associations directly to OUTER APPLY
                    projection = this.expressionBuilder.AddOuterJoinTest(projection);
                    Expression newFrom = new JoinExpression(JoinType.OuterApply, this.currentFrom, projection.Select, null);
                    this.currentFrom = newFrom;
                    return projection.Projector;
                }
                return projection;
            }
            else
            {
                Expression result = QueryBinder.BindMember(source, m.Member);
                MemberExpression mex = result as MemberExpression;
                if (mex != null && mex.Member == m.Member && mex.Expression == m.Expression)
                {
                    return m;
                }
                return result;
            }
        }
        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            Expression source = this.Visit(m.Expression);

            if (this.mapping.IsRelationship(m.Member))
            {
                ProjectionExpression projection = (ProjectionExpression)this.Visit(this.mapping.GetMemberExpression(source, m.Member));
                if (this.currentFrom != null && this.mapping.IsSingletonRelationship(m.Member))
                {
                    // convert singleton associations directly to OUTER APPLY
                    projection = projection.AddOuterJoinTest();
                    Expression newFrom = new JoinExpression(JoinType.OuterApply, this.currentFrom, projection.Source, null);
                    this.currentFrom = newFrom;
                    return projection.Projector;
                }
                return projection;
            }
            else
            {
                Expression result = QueryBinder.BindMember(source, m.Member);
                MemberExpression mex = result as MemberExpression;
                if (mex != null && mex.Member == m.Member && mex.Expression == m.Expression)
                {
                    return m;
                }
                return result;
            }
        }
        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 #6
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     // visit join in reverse order
     Expression condition = this.Visit(join.Condition);
     Expression right = this.VisitSource(join.Right);
     Expression left = this.VisitSource(join.Left);
     if (left != join.Left || right != join.Right || condition != join.Condition)
     {
         return new JoinExpression(join.Join, left, right, condition);
     }
     return join;
 }
Example #7
0
        protected override Expression VisitJoin(JoinExpression join)
        {
            var saveLastJoin = this.lastJoin;
            this.lastJoin = join.Join;
            join = (JoinExpression)base.VisitJoin(join);
            this.lastJoin = saveLastJoin;

            if (this.lastJoin != null && (join.Join == JoinType.CrossJoin) != (this.lastJoin == JoinType.CrossJoin)) {
                var result = this.MakeSubquery(join);
                return result;
            }
            return join;
        }
Example #8
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;
        }
Example #9
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     Expression result = base.VisitJoin(join);
     join = result as JoinExpression;
     if (join != null) {
         AliasedExpression right = join.Right as AliasedExpression;
         if (right != null) {
             AliasedExpression similarRight = (AliasedExpression)this.FindSimilarRight(join.Left as JoinExpression, join);
             if (similarRight != null) {
                 this.map.Add(right.Alias, similarRight.Alias);
                 return join.Left;
             }
         }
     }
     return result;
 }
Example #10
0
        protected override Expression VisitJoin(JoinExpression join)
        {
            if (join.Condition != null)
                this.Visit(join.Condition);
            else
                this.VisitSource(join.Right);

            SourceExpression left = this.VisitSource(join.Left);
            SourceExpression right = this.VisitSource(join.Right);
            Expression condition = this.Visit(join.Condition);
            if (left != join.Left || right != join.Right || condition != join.Condition)
            {
                return new JoinExpression(join.JoinType, left, right, condition);
            }
            return join;
        }
        protected override Expression VisitJoin(JoinExpression join)
        {
            join = (JoinExpression)base.VisitJoin(join);

            if (join.Join == JoinType.CrossApply || join.Join == JoinType.OuterApply)
            {
                if (join.Right is TableExpression)
                {
                    return new JoinExpression(JoinType.CrossJoin, join.Left, join.Right, null);
                }
                else
                {
                    SelectExpression select = join.Right as SelectExpression;
                    // Only consider rewriting cross apply if
                    //   1) right side is a select
                    //   2) other than in the where clause in the right-side select, no left-side declared aliases are referenced
                    //   3) and has no behavior that would change semantics if the where clause is removed (like groups, aggregates, take, skip, etc).
                    // Note: it is best to attempt this after redundant subqueries have been removed.
                    if (select != null
                        && select.Take == null
                        && select.Skip == null
                        && !AggregateChecker.HasAggregates(select)
                        && (select.GroupBy == null || select.GroupBy.Count == 0))
                    {
                        SelectExpression selectWithoutWhere = select.SetWhere(null);
                        HashSet<TableAlias> referencedAliases = ReferencedAliasGatherer.Gather(selectWithoutWhere);
                        HashSet<TableAlias> declaredAliases = DeclaredAliasGatherer.Gather(join.Left);
                        referencedAliases.IntersectWith(declaredAliases);
                        if (referencedAliases.Count == 0)
                        {
                            Expression where = select.Where;
                            select = selectWithoutWhere;
                            var pc = ColumnProjector.ProjectColumns(this.CanBeColumn, where, select.Columns, select.Alias, DeclaredAliasGatherer.Gather(select.From));
                            select = select.SetColumns(pc.Columns);
                            where = pc.Projector;
                            JoinType jt = (where == null) ? JoinType.CrossJoin : (join.Join == JoinType.CrossApply ? JoinType.InnerJoin : JoinType.LeftOuter);
                            return new JoinExpression(jt, join.Left, select, where);
                        }
                    }
                }
            }

            return join;
        }
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            if (isTopLevel)
            {
                isTopLevel = false;
                currentSelect = proj.Source;
                Expression projector = Visit(proj.Projector);
                if (projector != proj.Projector || currentSelect != proj.Source)
                {
                    return new ProjectionExpression(currentSelect, projector, proj.Aggregator);
                }
                return proj;
            }

            if (proj.IsSingleton && CanJoinOnServer(currentSelect))
            {
                TableAlias newAlias = new TableAlias();
                currentSelect = currentSelect.AddRedundantSelect(newAlias);

                // remap any references to the outer select to the new alias;
                SelectExpression source =
                    (SelectExpression) ColumnMapper.Map(proj.Source, newAlias, currentSelect.Alias);

                // add outer-join test
                ProjectionExpression pex = new ProjectionExpression(source, proj.Projector).AddOuterJoinTest();

                var pc = ColumnProjector.ProjectColumns(language.CanBeColumn, pex.Projector, currentSelect.Columns,
                                                        currentSelect.Alias, newAlias, proj.Source.Alias);

                JoinExpression join = new JoinExpression(JoinType.OuterApply, currentSelect.From, pex.Source, null);

                currentSelect = new SelectExpression(currentSelect.Alias, pc.Columns, join, null);
                return Visit(pc.Projector);
            }

            var saveTop = isTopLevel;
            var saveSelect = currentSelect;
            isTopLevel = true;
            currentSelect = null;
            Expression result = base.VisitProjection(proj);
            isTopLevel = saveTop;
            currentSelect = saveSelect;
            return result;
        }
Example #13
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     join = (JoinExpression)base.VisitJoin(join);
     if (join.Join == JoinType.CrossJoin && this.currentWhere != null) {
         // try to figure out which parts of the current where expression can be used for a join condition
         var declaredLeft = DeclaredAliasGatherer.Gather(join.Left);
         var declaredRight = DeclaredAliasGatherer.Gather(join.Right);
         var declared = new HashSet<TableAlias>(declaredLeft.Union(declaredRight));
         var exprs = this.currentWhere.Split(ExpressionType.And, ExpressionType.AndAlso);
         var good = exprs.Where(e => CanBeJoinCondition(e, declaredLeft, declaredRight, declared)).ToList();
         if (good.Count > 0) {
             var condition = good.Join(ExpressionType.And);
             join = this.UpdateJoin(join, JoinType.InnerJoin, join.Left, join.Right, condition);
             var newWhere = exprs.Where(e => !good.Contains(e)).Join(ExpressionType.And);
             this.currentWhere = newWhere;
         }
     }
     return join;
 }
 protected override Expression VisitJoin(JoinExpression join)
 {
     join = (JoinExpression)base.VisitJoin(join);
     if (join.JoinType == JoinType.CrossJoin && _currentWhere != null)
     {
         // try to figure out which parts of the current where expression can be used for a join condition
         var declaredLeft  = DeclaredAliasGatherer.Gather(join.Left);
         var declaredRight = DeclaredAliasGatherer.Gather(join.Right);
         var declared      = new HashSet <TableAlias>(declaredLeft.Union(declaredRight));
         var exprs         = _currentWhere.Split(ExpressionType.And, ExpressionType.AndAlso);
         var good          = exprs.Where(e => CanBeJoinCondition(e, declaredLeft, declaredRight, declared)).ToList();
         if (good.Count > 0)
         {
             var condition = good.Join(ExpressionType.And);
             join = join.Update(JoinType.InnerJoin, join.Left, join.Right, condition);
             var newWhere = exprs.Where(e => !good.Contains(e)).Join(ExpressionType.And);
             _currentWhere = newWhere;
         }
     }
     return(join);
 }
        public void GetSupersetAlias_ExprsNoSupersetExpr_Null()
        {
            List <IExpression> exprs = new List <IExpression>();

            IExpression expr1 = ModelResolvers.ExprResolver();

            expr1.Structure = ModelResolvers.DsResolver();
            expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
            expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "Id2"));

            IExpression expr2 = ModelResolvers.ExprResolver();

            expr2.Structure = ModelResolvers.DsResolver();
            expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
            expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "Id3"));

            exprs.Add(expr1);
            exprs.Add(expr2);

            Assert.Null(JoinExpression.GetSupersetAlias(exprs));
        }
Example #16
0
        /// <summary>
        /// Visits the join.
        /// </summary>
        /// <param name="join">The join.</param>
        /// <returns></returns>
        protected override Expression VisitJoin(JoinExpression join)
        {
            join = (JoinExpression)base.VisitJoin(join);

            if (join.Join == JoinType.CrossApply || join.Join == JoinType.OuterApply)
            {
                if (join.Right is TableExpression)
                {
                    return(new JoinExpression(JoinType.CrossJoin, join.Left, join.Right, null));
                }
                else
                {
                    SelectExpression select = join.Right as SelectExpression;
                    // Only consider rewriting cross apply if
                    //   1) right side is a select
                    //   2) other than in the where clause in the right-side select, no left-side declared aliases are referenced
                    //   3) and has no behavior that would change semantics if the where clause is removed (like groups, aggregates, take, skip, etc).
                    // Note: it is best to attempt this after redundant subqueries have been removed.
                    if (select != null && select.Take == null && select.Skip == null && !AggregateChecker.HasAggregates(select) && (select.GroupBy == null || select.GroupBy.Count == 0))
                    {
                        SelectExpression     selectWithoutWhere = select.SetWhere(null);
                        HashSet <TableAlias> referencedAliases  = ReferencedAliasGatherer.Gather(selectWithoutWhere);
                        HashSet <TableAlias> declaredAliases    = DeclaredAliasGatherer.Gather(join.Left);
                        referencedAliases.IntersectWith(declaredAliases);
                        if (referencedAliases.Count == 0)
                        {
                            Expression where = select.Where;
                            select           = selectWithoutWhere;
                            var pc = ColumnProjector.ProjectColumns(this.language, where, select.Columns, select.Alias, DeclaredAliasGatherer.Gather(select.From));
                            select = select.SetColumns(pc.Columns);
                            where  = pc.Projector;
                            JoinType jt = (where == null) ? JoinType.CrossJoin : (join.Join == JoinType.CrossApply ? JoinType.InnerJoin : JoinType.LeftOuter);
                            return(new JoinExpression(jt, join.Left, select, where));
                        }
                    }
                }
            }

            return(join);
        }
        public void GetAliasesSignatures_CompName_Signatures(string compName)
        {
            JoinExpression joinExpr = new JoinExpression(TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol));

            joinExpr.AddOperand("ds", ModelResolvers.ExprResolver());

            IExpression expr1 = TestExprFactory.GetExpression("get", ExpressionFactoryNameTarget.OperatorSymbol);

            expr1.Structure = ModelResolvers.DsResolver();
            expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "comp1"));
            expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "comp2"));

            IExpression expr2 = TestExprFactory.GetExpression("ref", ExpressionFactoryNameTarget.OperatorSymbol);

            expr2.Structure = ModelResolvers.DsResolver();
            expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "comp1"));
            expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "comp3"));

            joinExpr.Operands["ds"].AddOperand("ds_1", expr1);
            joinExpr.Operands["ds"].AddOperand("ds_2", expr2);

            List <string> expected = new List <string>();

            if (compName != "comp4")
            {
                expected.Add("ds_1");
            }
            if (!compName.In("comp2", "comp4"))
            {
                expected.Add("ds_2");
            }

            string[] result = joinExpr.GetAliasesSignatures(compName);

            Assert.Equal(expected.Count, result.Length);
            for (int i = 0; i < expected.Count; i++)
            {
                Assert.Equal(expected[i], result[i]);
            }
        }
        public void GetSubsetAliasStructure_SubsetStructure()
        {
            for (int i = 0; i < 2; i++)
            {
                JoinExpression joinExpr = new JoinExpression(TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol));
                joinExpr.AddOperand("ds", ModelResolvers.ExprResolver());

                IExpression expr1 = ModelResolvers.ExprResolver();
                expr1.Structure = ModelResolvers.DsResolver();
                expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
                expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "Id2"));

                IExpression expr2 = ModelResolvers.ExprResolver();
                expr2.Structure = ModelResolvers.DsResolver();
                expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
                expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "Id2"));

                joinExpr.Operands["ds"].AddOperand("ds_1", expr1);
                joinExpr.Operands["ds"].AddOperand("ds_2", expr2);

                IExpression expr3 = ModelResolvers.ExprResolver();
                if (i == 1)
                {
                    expr3.Structure = ModelResolvers.DsResolver();
                    expr3.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
                    joinExpr.Operands["ds"].AddOperand("ds_3", expr3);
                }

                IDataStructure result = joinExpr.GetSubsetAliasStructure();

                if (i == 0)
                {
                    Assert.True(expr1.Structure.EqualsObj(result));
                }
                else
                {
                    Assert.True(expr3.Structure.EqualsObj(result));
                }
            }
        }
        protected override Expression VisitJoin(JoinExpression join)
        {
            var result = base.VisitJoin(join);

            join = result as JoinExpression;

            if (join != null)
            {
                var right = join.Right as AliasedExpression;
                if (right != null)
                {
                    var similarRight = (AliasedExpression)FindSimilarRight(join.Left as JoinExpression, join);
                    if (similarRight != null)
                    {
                        map.Add(right.Alias, similarRight.Alias);
                        return(join.Left);
                    }
                }
            }

            return(result);
        }
    protected internal override Expression VisitJoin(JoinExpression join)
    {
        SourceExpression left      = this.VisitSource(join.Left);
        SourceExpression right     = this.VisitSource(join.Right);
        Expression?      condition = this.Visit(join.Condition);

        if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply)
        {
            if (right is TableExpression)
            {
                return(new JoinExpression(join.JoinType == JoinType.OuterApply ? JoinType.LeftOuterJoin : JoinType.InnerJoin, left, right,
                                          Schema.Current.Settings.IsPostgres ? (Expression) new SqlConstantExpression(true) :
                                          Expression.Equal(new SqlConstantExpression(1), new SqlConstantExpression(1))));
            }
        }

        if (left != join.Left || right != join.Right || condition != join.Condition)
        {
            return(new JoinExpression(join.JoinType, left, right, condition));
        }
        return(join);
    }
        public void GetSubsetAlias_Exprs_SubsetExpr()
        {
            for (int i = 0; i < 2; i++)
            {
                List <IExpression> exprs = new List <IExpression>();

                IExpression expr1 = ModelResolvers.ExprResolver();
                expr1.Structure = ModelResolvers.DsResolver();
                expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
                expr1.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "Id2"));

                IExpression expr2 = ModelResolvers.ExprResolver();
                expr2.Structure = ModelResolvers.DsResolver();
                expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
                expr2.Structure.Identifiers.Add(new StructureComponent(BasicDataType.String, "Id2"));

                exprs.Add(expr1);
                exprs.Add(expr2);

                IExpression expr3 = ModelResolvers.ExprResolver();
                if (i == 1)
                {
                    expr3.Structure = ModelResolvers.DsResolver();
                    expr3.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer, "Id1"));
                    exprs.Add(expr3);
                }

                IExpression result = JoinExpression.GetSubsetAlias(exprs);

                if (i == 0)
                {
                    Assert.Equal(expr1, result);
                }
                else
                {
                    Assert.Equal(expr3, result);
                }
            }
        }
        private void TranslateJoin(JoinExpression node)
        {
            Translate(node.Source);

            var joined = node.Joined as CollectionExpression;

            if (joined == null)
            {
                throw new NotSupportedException("Only a collection is allowed to be joined.");
            }

            var localFieldValue = AggregateLanguageTranslator.Translate(node.SourceKeySelector);

            if (localFieldValue.BsonType != BsonType.String)
            {
                throw new NotSupportedException("Could not translate the local field.");
            }

            var localField = localFieldValue.ToString().Substring(1); // remove '$'

            var foreignFieldValue = AggregateLanguageTranslator.Translate(node.SourceKeySelector);

            if (foreignFieldValue.BsonType != BsonType.String)
            {
                throw new NotSupportedException("Could not translate the foreign field.");
            }

            var foreignField = foreignFieldValue.ToString().Substring(1); // remove '$'

            _stages.Add(new BsonDocument("$lookup", new BsonDocument
            {
                { "from", ((CollectionExpression)node.Joined).CollectionNamespace.CollectionName },
                { "localField", localField },
                { "foreignField", foreignField },
                { "as", node.JoinedItemName }
            }));

            _stages.Add(new BsonDocument("$unwind", "$" + node.JoinedItemName));
        }
Example #23
0
        private IJoinQuery<TResult> Join<TR, TKey, TResult>(string type, IQuery<TR> rightQuery, Expression<Func<T, TKey>> leftKeySelector, Expression<Func<TR, TKey>> rightKeySelector, Expression<Func<T, TR, TResult>> resultSelector) where TR : BaseDBModel, new()
        {
            var rightTableAlias = "t" + (JoinTableCount + 1);
            var dynamicParameters = new DynamicParameters();
            dynamicParameters.AddDynamicParams(Param);
            var left = new JoinExpression(leftKeySelector, Map, dynamicParameters);

            var right = new JoinExpression(rightKeySelector, new Dictionary<string, string> { { "", rightTableAlias } }, dynamicParameters);
            StringBuilder sqlJoin = new StringBuilder();
            foreach (var v in left.JoinDic)
            {
                if (sqlJoin.Length > 0)
                {
                    sqlJoin.Append(" AND ");
                }
                sqlJoin.Append("(");
                sqlJoin.Append(v.Value);
                sqlJoin.Append("=");
                sqlJoin.Append(right.JoinDic[v.Key]);
                sqlJoin.Append(")");
            }
            var joinStr = $"{JoinStr} {type} JOIN {DBTool.GetTableName(rightQuery.DBModel)} {rightTableAlias} ON {sqlJoin}";

            var sel = new JoinResultMapExpression(resultSelector, Map, rightTableAlias, dynamicParameters);
            StringBuilder sqlWhere = new StringBuilder(Where);

            var where = new WhereExpression(rightQuery.WhereExpression, rightTableAlias, dynamicParameters);
            if (!string.IsNullOrEmpty(where.SqlCmd))
            {
                if (sqlWhere.Length > 0)
                {
                    sqlWhere.Append(" AND ");
                }
                sqlWhere.Append(where.SqlCmd);
            }

            return new JoinQueryInfo<TResult>(joinStr, JoinTableCount + 1, sel.MapList, sqlWhere.ToString(), dynamicParameters);
        }
Example #24
0
        /// <summary>
        /// Renders a TSQL translated code for an "if-then-else" operator identifier.
        /// </summary>
        /// <param name="identifier">The idenfitier.</param>
        /// <returns>The TSQL translated code.</returns>
        private string RenderIfThenElseIdentifier(StructureComponent identifier)
        {
            // Get aliases of every "if-then-else" branch:
            IExpression[] ifExprAliases = this.joinExpr.Operands["ds"].OperandsCollection
                                          .Where(alias => alias.ParamSignature.In(this.joinExpr.Operands["apply"].Operands["if"].GetDescendantExprs("Alias").Select(a => a.ExpressionText).ToArray())).ToArray();
            IExpression[] thenExprAliases = this.joinExpr.Operands["ds"].OperandsCollection
                                            .Where(alias => alias.ParamSignature.In(this.joinExpr.Operands["apply"].Operands["then"].GetDescendantExprs("Alias").Select(a => a.ExpressionText).ToArray())).ToArray();
            IExpression[] elseExprAliases = this.joinExpr.Operands["ds"].OperandsCollection
                                            .Where(alias => alias.ParamSignature.In(this.joinExpr.Operands["apply"].Operands["else"].GetDescendantExprs("Alias").Select(a => a.ExpressionText).ToArray())).ToArray();

            // Get subset alias of every "if-then-else" branch:
            IExpression ifExprAlias   = JoinExpression.GetSubsetAlias(ifExprAliases);
            IExpression thenExprAlias = JoinExpression.GetSubsetAlias(thenExprAliases);
            IExpression elseExprAlias = JoinExpression.GetSubsetAlias(elseExprAliases);

            if (thenExprAlias != null && elseExprAlias != null)
            {
                IExpression ifSubExpr = this.joinExpr.Operands["apply"].Operands["if"].Operands["ds_1"];
                string      suffix    = ifSubExpr.OperatorSymbol.In("ref", "const") ? " = 1" : string.Empty;

                return
                    ($"IIF({this._opRendererResolver(ifSubExpr.OperatorSymbol).Render(ifSubExpr, ifExprAlias?.Structure.Measures[0] ?? this.joinExpr.Operands["apply"].Operands["then"].Structure.Measures[0])}{suffix}, " +
                     $"{thenExprAlias.ParamSignature}.{identifier.ComponentName}, " +
                     $"{elseExprAlias.ParamSignature}.{identifier.ComponentName}) AS {identifier.ComponentName},");
            }
            else if (thenExprAlias != null)
            {
                return($"{thenExprAlias.ParamSignature}.{identifier.ComponentName},");
            }
            else if (elseExprAlias != null)
            {
                return($"{elseExprAlias.ParamSignature}.{identifier.ComponentName},");
            }
            else
            {
                return($"{ifExprAlias.ParamSignature}.{identifier.ComponentName},");
            }
        }
Example #25
0
        private void VisitTableExpression(TableExpression table)
        {
            if (table is JoinExpression)
            {
                JoinExpression jt = (JoinExpression)table;
                sql.Append($"{Environment.NewLine}\t{jt.JoinType} {jt.Entity.MainTable.FullName} AS [{jt.Alias}]");
                if (jt.Hint != HintTypes.NoneHint)
                {
                    sql.Append($" WITH({jt.Hint})");
                }

                sql.Append("\n\tON");
                VisitBooleanFunction(jt.ON);
            }
            else if (table is TableExpression)
            {
                sql.Append($"{Environment.NewLine}\t{table.Entity.MainTable.FullName} AS [{table.Alias}]");
                if (table.Hint != HintTypes.NoneHint)
                {
                    sql.Append($" WITH({table.Hint})");
                }
            }
        }
    protected internal override Expression VisitJoin(JoinExpression join)
    {
        if (join.JoinType == JoinType.SingleRowLeftOuterJoin)
        {
            var source = (SourceWithAliasExpression)join.Right;

            var hs = allColumnsUsed.TryGetC(source.Alias);

            if (hs == null || hs.Count == 0)
            {
                return(Visit(join.Left));
            }
        }

        if (join.JoinType == JoinType.OuterApply || join.JoinType == JoinType.LeftOuterJoin)
        {
            if (join.Right is SelectExpression sql && sql.IsOneRow())
            {
                var hs = allColumnsUsed.TryGetC(sql.Alias);
                if (hs == null || hs.Count == 0)
                {
                    return(Visit(join.Left));
                }
            }
        }

        // visit join in reverse order
        Expression?      condition = this.Visit(join.Condition);
        SourceExpression right     = this.VisitSource(join.Right);
        SourceExpression left      = this.VisitSource(join.Left);

        if (left != join.Left || right != join.Right || condition != join.Condition)
        {
            return(new JoinExpression(join.JoinType, left, right, condition));
        }
        return(join);
    }
Example #27
0
        private Expression BindGroupJoin(MethodCallExpression call)
        {
            Expression       outerSource    = call.Arguments[0];
            Expression       innerSource    = call.Arguments[1];
            LambdaExpression outerKey       = GetLambda(call.Arguments[2]);
            LambdaExpression innerKey       = GetLambda(call.Arguments[3]);
            LambdaExpression resultSelector = GetLambda(call.Arguments[4]);

            ProjectionExpression outerProjection = VisitSequence(outerSource);
            ProjectionExpression innerProjection = VisitSequence(innerSource);

            _map[outerKey.Parameters[0]] = outerProjection.Projector;
            Expression outerKeyExpr = Visit(outerKey.Body);

            _map[innerKey.Parameters[0]] = innerProjection.Projector;
            Expression innerKeyExpr = Visit(innerKey.Body);

            LambdaExpression predicate = Expression.Lambda(Expression.Equal(innerKey.Body, outerKey.Body), innerKey.Parameters[0]);
            Expression       subquery  = Expression.Call(typeof(Queryable), nameof(Queryable.Where), new[] { innerKey.Parameters[0].Type }, innerSource, predicate);

            _map[resultSelector.Parameters[0]] = outerProjection.Projector;
            _map[resultSelector.Parameters[1]] = Visit(subquery);
            Expression resultExpr = Visit(resultSelector.Body);

            JoinExpression join = new JoinExpression(JoinType.InnerJoin, outerProjection.Source, innerProjection.Source, Expression.Equal(outerKeyExpr, innerKeyExpr));

            var groupedColumns = ProjectColumns(outerKeyExpr, outerProjection.Source.Alias, outerProjection.Source.Alias);
            IEnumerable <Expression> groupExprs = groupedColumns.Columns.Select(c => c.Expression);

            string           alias = GetNewAlias();
            ProjectedColumns pc    = ProjectColumns(resultExpr, alias, outerProjection.Source.Alias, innerProjection.Source.Alias);

            return(new ProjectionExpression(
                       new SelectExpression(alias, pc.Columns, join, groupBy: groupExprs),
                       pc.Projector
                       ));
        }
Example #28
0
        protected override Expression VisitJoin(JoinExpression join)
        {
            this.VisitJoinLeft(join.Left);
            this.WriteLine(Indentation.Same);
            switch (join.Join)
            {
            case JoinType.CrossJoin:
                this.Write(", ");
                break;

            case JoinType.InnerJoin:
                this.Write("INNER JOIN ");
                break;

            case JoinType.CrossApply:
                this.Write("CROSS APPLY ");
                break;

            case JoinType.OuterApply:
                this.Write("OUTER APPLY ");
                break;

            case JoinType.LeftOuter:
            case JoinType.SingletonLeftOuter:
                this.Write("LEFT OUTER JOIN ");
                break;
            }
            this.VisitJoinRight(join.Right);
            if (join.Condition != null)
            {
                this.WriteLine(Indentation.Inner);
                this.Write("ON ");
                this.VisitPredicate(join.Condition);
                this.Indent(Indentation.Outer);
            }
            return(join);
        }
Example #29
0
        protected override Expression VisitMember(MemberExpression m)
        {
            var       source = Visit(m.Expression);
            IProperty property;

            // **fix** 解决无法返回两级以上关联对象的问题
            // var ex = source as EntityExpression
            // if (ex != null &&
            if ((property = PropertyUnity.GetProperty(m.Expression.Type, m.Member.Name)) != null &&
                property is RelationProperty)
            {
                var projection = (ProjectionExpression)Visit(QueryUtility.GetMemberExpression(source, property));
                if (currentFrom != null && m.Member.GetMemberType().GetEnumerableType() == null)
                {
                    // convert singleton associations directly to OUTER APPLY
                    projection = projection.AddOuterJoinTest();
                    var newFrom = new JoinExpression(JoinType.OuterApply, currentFrom, projection.Select, null);
                    currentFrom = newFrom;
                    return(projection.Projector);
                }

                return(projection);
            }

            var result = QueryBinder.BindMember(source, m.Member);
            var mex    = result as MemberExpression;

            if (mex != null &&
                mex.Member == m.Member &&
                mex.Expression == m.Expression)
            {
                return(m);
            }

            return(result);
        }
        public void Constructor_JoinOperatorExpr_JoinExpr()
        {
            IExpression           expr    = TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol);
            IExpression           refExpr = ModelResolvers.ExprResolver();
            ITransformationSchema schema  = ModelResolvers.SchemaResolver();

            refExpr.AddOperand("ds", expr);
            expr.ContainingSchema    = schema;
            expr.ReferenceExpression = refExpr;

            JoinExpression joinExpr = new JoinExpression(expr);

            Assert.Equal(expr.ParentExpression, joinExpr.ParentExpression);
            Assert.Equal(expr.ContainingSchema, joinExpr.ContainingSchema);
            Assert.Equal(expr.ExpressionText, joinExpr.ExpressionText);
            Assert.Equal(expr.LineNumber, joinExpr.LineNumber);
            Assert.Equal(expr.OperandsCollection, joinExpr.OperandsCollection);
            Assert.Equal(expr.OperatorDefinition, joinExpr.OperatorDefinition);
            Assert.Equal(expr.ParamSignature, joinExpr.ParamSignature);
            Assert.Equal(expr.ReferenceExpression, joinExpr.ReferenceExpression);
            Assert.Equal(expr.ResultName, joinExpr.ResultName);
            Assert.Equal(expr.Structure, joinExpr.Structure);
            Assert.Null(joinExpr.BasicStructure);
        }
        protected virtual Expression BindSelectMany(Type resultType, Expression source, LambdaExpression collectionSelector, LambdaExpression resultSelector)
        {
            ProjectionExpression projection = this.VisitSequence(source);
            this.map[collectionSelector.Parameters[0]] = projection.Projector;

            Expression collection = collectionSelector.Body;

            // check for DefaultIfEmpty
            bool defaultIfEmpty = false;
            MethodCallExpression mcs = collection as MethodCallExpression;
            if (mcs != null && mcs.Method.Name == "DefaultIfEmpty" && mcs.Arguments.Count == 1 &&
                (mcs.Method.DeclaringType == typeof(Queryable) || mcs.Method.DeclaringType == typeof(Enumerable)))
            {
                collection = mcs.Arguments[0];
                defaultIfEmpty = true;
            }

            ProjectionExpression collectionProjection = (ProjectionExpression)this.VisitSequence(collection);
            bool isTable = collectionProjection.Select.From is TableExpression;
            JoinType joinType = isTable ? JoinType.CrossJoin : defaultIfEmpty ? JoinType.OuterApply : JoinType.CrossApply;
            if (joinType == JoinType.OuterApply)
            {
                collectionProjection = this.language.AddOuterJoinTest(collectionProjection);
            }
            JoinExpression join = new JoinExpression(joinType, projection.Select, collectionProjection.Select, null);

            var alias = this.GetNextAlias();
            ProjectedColumns pc;
            if (resultSelector == null)
            {
                pc = this.ProjectColumns(collectionProjection.Projector, alias, projection.Select.Alias, collectionProjection.Select.Alias);
            }
            else
            {
                this.map[resultSelector.Parameters[0]] = projection.Projector;
                this.map[resultSelector.Parameters[1]] = collectionProjection.Projector;
                Expression result = this.Visit(resultSelector.Body);
                pc = this.ProjectColumns(result, alias, projection.Select.Alias, collectionProjection.Select.Alias);
            }
            return new ProjectionExpression(
                new SelectExpression(alias, pc.Columns, join, null),
                pc.Projector
                );
        }
 protected override Expression VisitJoin(JoinExpression join)
 {
     // make sure order by expressions lifted up from the left side are not lost
     // when visiting the right side
     Expression left = this.VisitSource(join.Left);
     IList<OrderExpression> leftOrders = this.gatheredOrderings;
     this.gatheredOrderings = null; // start on the right with a clean slate
     Expression right = this.VisitSource(join.Right);
     this.PrependOrderings(leftOrders);
     Expression condition = this.Visit(join.Condition);
     if (left != join.Left || right != join.Right || condition != join.Condition)
     {
         return new JoinExpression(join.Join, left, right, condition);
     }
     return join;
 }
Example #33
0
        /// <summary>
        /// Visits the projection.
        /// </summary>
        /// <param name="proj">The proj.</param>
        /// <returns></returns>
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            SelectExpression save = this.currentSelect;

            this.currentSelect = proj.Select;
            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.Select, newOuterSelect.Alias, save.Alias);
                        // add outer-join test
                        ProjectionExpression newInnerProjection = this.language.AddOuterJoinTest(new ProjectionExpression(newInnerSelect, proj.Projector));
                        newInnerSelect = newInnerProjection.Select;
                        Expression newProjector = newInnerProjection.Projector;

                        TableAlias newAlias = new TableAlias();
                        var        pc       = ColumnProjector.ProjectColumns(this.language, newProjector, null, 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, false);

                        // 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
                    {
                        bool saveJoin = this.canJoinOnClient;
                        this.canJoinOnClient = false;
                        var result = base.VisitProjection(proj);
                        this.canJoinOnClient = saveJoin;
                        return(result);
                    }
                }
                else
                {
                    this.isTopLevel = false;
                }
                return(base.VisitProjection(proj));
            }
            finally
            {
                this.currentSelect = save;
            }
        }
Example #34
0
 protected override Expression GetInsertResult(MappingEntity entity, Expression instance,
                                               LambdaExpression selector, Dictionary<MemberInfo, Expression> map)
 {
     var tables = _mapping.GetTables(entity);
     if (tables.Count <= 1)
     {
         return base.GetInsertResult(entity, instance, selector, map);
     }
     var aliases = new Dictionary<string, TableAlias>();
     MappingTable rootTable = tables.Single(ta => !_mapping.IsExtensionTable(ta));
     var tableExpression = new TableExpression(new TableAlias(), entity, _mapping.GetTableName(rootTable));
     var aggregator = Aggregator.GetAggregator(selector.Body.Type,
                                               typeof (IEnumerable<>).MakeGenericType(selector.Body.Type));
     aliases.Add(_mapping.GetAlias(rootTable), tableExpression.Alias);
     Expression source = tableExpression;
     foreach (MappingTable table in tables.Where(t => _mapping.IsExtensionTable(t)))
     {
         TableAlias joinedTableAlias = new TableAlias();
         string extensionAlias = _mapping.GetAlias(table);
         aliases.Add(extensionAlias, joinedTableAlias);
         List<string> keyColumns = _mapping.GetExtensionKeyColumnNames(table).ToList();
         List<MemberInfo> relatedMembers = _mapping.GetExtensionRelatedMembers(table).ToList();
         string relatedAlias = _mapping.GetExtensionRelatedAlias(table);
         TableAlias relatedTableAlias;
         aliases.TryGetValue(relatedAlias, out relatedTableAlias);
         TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, _mapping.GetTableName(table));
         Expression cond = null;
         for (int i = 0, n = keyColumns.Count; i < n; i++)
         {
             var memberType = TypeHelper.GetMemberType(relatedMembers[i]);
             var colType = GetColumnType(entity, relatedMembers[i]);
             var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias,
                                                      _mapping.GetColumnName(entity, relatedMembers[i]));
             var joinedColumn = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]);
             var eq = joinedColumn.Equal(relatedColumn);
             cond = (cond != null) ? cond.And(eq) : eq;
         }
         source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond);
     }
     Expression where;
     DeclarationCommand genIdCommand = null;
     var generatedIds =
         _mapping.GetMappedMembers(entity).Where(
             m => _mapping.IsPrimaryKey(entity, m) && _mapping.IsGenerated(entity, m)).ToList();
     if (generatedIds.Count > 0)
     {
         if (map == null || !generatedIds.Any(m => map.ContainsKey(m)))
         {
             var localMap = new Dictionary<MemberInfo, Expression>();
             genIdCommand = GetGeneratedIdCommand(entity, generatedIds.ToList(), localMap);
             map = localMap;
         }
         var mex = selector.Body as MemberExpression;
         if (mex != null && _mapping.IsPrimaryKey(entity, mex.Member) && _mapping.IsGenerated(entity, mex.Member))
         {
             if (genIdCommand != null)
             {
                 return new ProjectionExpression(
                     genIdCommand.Source,
                     new ColumnExpression(mex.Type, genIdCommand.Variables[0].QueryType,
                                          genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                     aggregator
                     );
             }
             TableAlias alias = new TableAlias();
             var colType = GetColumnType(entity, mex.Member);
             return new ProjectionExpression(
                 new SelectExpression(alias, new[] {new ColumnDeclaration("", map[mex.Member], colType)},
                                      null, null),
                 new ColumnExpression(TypeHelper.GetMemberType(mex.Member), colType, alias, ""),
                 aggregator
                 );
         }
         where = generatedIds.Select((m, i) =>
                                     GetMemberExpression(source, entity, m).Equal(map[m])
             ).Aggregate((x, y) => x.And(y));
     }
     else
     {
         where = GetIdentityCheck(tableExpression, entity, instance);
     }
     var columns = new List<ColumnDeclaration>();
     GetColumns(entity, aliases, columns);
     SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null);
     Expression typeProjector = GetEntityExpression(tableExpression, entity);
     Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
     TableAlias newAlias = new TableAlias();
     var pc = ColumnProjector.ProjectColumns(Translator.Linguist.Language, selection, null, newAlias,
                                             tableExpression.Alias);
     var pe = new ProjectionExpression(
         new SelectExpression(newAlias, pc.Columns, root, where),
         pc.Projector,
         aggregator
         );
     if (genIdCommand != null)
     {
         return new BlockCommand(genIdCommand, pe);
     }
     return pe;
 }
Example #35
0
        public override ProjectionExpression GetQueryExpression(MappingEntity entity)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count <= 1)
            {
                return base.GetQueryExpression(entity);
            }

            var aliases = new Dictionary<string, TableAlias>();
            MappingTable rootTable = tables.Single(ta => !this.mapping.IsExtensionTable(ta));
            var tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(rootTable));
            aliases.Add(this.mapping.GetAlias(rootTable), tex.Alias);
            Expression source = tex;

            foreach (MappingTable table in tables.Where(t => this.mapping.IsExtensionTable(t)))
            {
                TableAlias joinedTableAlias = new TableAlias();
                string extensionAlias = this.mapping.GetAlias(table);
                aliases.Add(extensionAlias, joinedTableAlias);

                List<string> keyColumns = this.mapping.GetExtensionKeyColumnNames(table).ToList();
                List<MemberInfo> relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToList();
                string relatedAlias = this.mapping.GetExtensionRelatedAlias(table);

                TableAlias relatedTableAlias;
                aliases.TryGetValue(relatedAlias, out relatedTableAlias);

                TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, this.mapping.GetTableName(table));

                Expression cond = null;
                for (int i = 0, n = keyColumns.Count; i < n; i++)
                {
                    var memberType = TypeHelper.GetMemberType(relatedMembers[i]);
                    var colType = this.GetColumnType(entity, relatedMembers[i]);
                    var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias, this.mapping.GetColumnName(entity, relatedMembers[i]));
                    var joinedColumn = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]);
                    var eq = joinedColumn.Equal(relatedColumn);
                    cond = (cond != null) ? cond.And(eq) : eq;
                }

                source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond);
            }

            var columns = new List<ColumnDeclaration>();
            this.GetColumns(entity, aliases, columns);
            SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null);
            var existingAliases = aliases.Values.ToArray();

            Expression projector = this.GetEntityExpression(root, entity);
            var selectAlias = new TableAlias();
            var pc = ColumnProjector.ProjectColumns(this.Translator.Linguist.Language, projector, null, selectAlias, root.Alias);
            var proj = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, root, null),
                pc.Projector
                );

            return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType);
        }
            private static IEnumerable<ColumnExpression> KeysJoin(JoinExpression join)
            {
                switch (join.JoinType)
                {
                    case JoinType.SingleRowLeftOuterJoin:
                        return Keys(join.Left);

                    case JoinType.CrossJoin:
                    case JoinType.InnerJoin:
                    case JoinType.CrossApply:
                    case JoinType.OuterApply:
                    case JoinType.LeftOuterJoin:
                    case JoinType.RightOuterJoin:
                    case JoinType.FullOuterJoin:
                        return Keys(join.Left).Concat(Keys(join.Right));
                    default:
                        break;
                }

                throw new InvalidOperationException("Unexpected Join Type");
            }
 protected virtual Expression VisitJoin(JoinExpression join)
 {
     Expression left = this.VisitSource(join.Left);
     Expression right = this.VisitSource(join.Right);
     Expression condition = this.Visit(join.Condition);
     if (left != join.Left || right != join.Right || condition != join.Condition)
     {
         return new JoinExpression(join.Join, left, right, condition);
     }
     return join;
 }
        public Expression Parse(string expr, CompileContext ctx = null, Dictionary <Expression, ExpressionSegment> segments = null)
        {
            if (expr == null)
            {
                throw new Exception("expr null");
            }
            expr = expr.Trim();

            if (string.IsNullOrEmpty(expr))
            {
                throw new Exception("expr empty");
            }

            Expression result;

            if (cachedExprs.TryGetValue(expr, out result))
            {
                return(result);
            }

            Stack <Expression>     s1        = new Stack <Expression>();
            Stack <PartInfo>       s2        = new Stack <PartInfo>();
            Stack <string>         variables = new Stack <string>();
            Stack <CompileContext> ctxs      = new Stack <CompileContext>();

            ctxs.Push(ctx);
            PushScope(ctxs);


            foreach (var segment in ToParts(expr))
            {
                if (segment.IsString)
                {
                    s1.Push(Expression.Constant <string>(segment.Expr));
                    //s1.Push((Expression)part1);
                    if (segments != null)
                    {
                        segments[s1.Peek()] = segment;
                    }
                    continue;
                }
                string exprPart = segment.Expr;
                Console.WriteLine("part:" + exprPart);
                if (kws.ContainsKey(exprPart))
                // if(segment.IsKeyword)
                {
                    var part = new PartInfo()
                    {
                        segment     = segment,
                        keywordInfo = kws[exprPart]
                    };
                    var kw = part.keywordInfo;
                    if (kw.Keyword == ")")
                    {
                        while (s2.Count > 0 && s2.Peek().keywordInfo.Keyword != "(")
                        {
                            var tmp = s2.Pop();
                            s1.Push(GetExpr(tmp, s1, s2));

                            if (s2.Peek().keywordInfo.Keyword == ",")
                            {
                            }
                        }
                        Expression contentNode;
                        if (s1.Peek().ExpressionType != ExpressionType.Group)
                        {
                            contentNode = PopData(s1);
                        }
                        else
                        {
                            contentNode = null;
                        }
                        if (s1.Peek() is JoinExpression)
                        {
                            var join = s1.Pop() as JoinExpression;
                            //join.List.Insert(0, contentNode);
                            join.List.Add(contentNode);
                            contentNode = join;
                        }
                        //pop group
                        s1.Pop();
                        bool isGroup = true;

                        if (s1.Count > 0 && (s1.Peek().ExpressionType == ExpressionType.Member || s1.Peek().ExpressionType == ExpressionType.Variable))
                        {
                            Expression[] args = null;
                            if (contentNode == null)
                            {
                                args = null;
                            }
                            else if (contentNode is JoinExpression)
                            {
                                args = ((JoinExpression)contentNode).List.ToArray();
                            }
                            else
                            {
                                args = new Expression[] { contentNode };
                            }
                            var d = s1.Peek() as MemberExpression;
                            if (d != null)
                            {
                                if (d.Member.MemberType == MemberTypes.Method)
                                {
                                    s1.Pop();
                                    s1.Push(Expression.Call(d.Instance, d.Member.Name, args));
                                    if (segments != null)
                                    {
                                        var seg = segments[d];
                                        segments.Remove(d);
                                        segments[s1.Peek()] = seg;
                                    }
                                }
                            }
                            else
                            {
                                var p = s1.Peek() as ParameterExpression;

                                if (p.ValueType == typeof(MethodInfo))
                                {
                                    MethodInfo mInfo = ctx.Context.GetVariable(p.Name) as MethodInfo;
                                    s1.Pop();
                                    s1.Push(Expression.Call(mInfo, args));
                                    if (segments != null)
                                    {
                                        var seg = segments[p];
                                        segments.Remove(p);
                                        segments[s1.Peek()] = seg;
                                    }
                                }
                                else if (p.ValueType.IsSubclassOf(typeof(Delegate)))
                                {
                                    Type delType = p.ValueType;
                                    var  mInfo   = delType.GetMethod("Invoke");

                                    s1.Push(Expression.Call(s1.Pop(), mInfo.ReturnType, args));
                                    if (segments != null)
                                    {
                                        var seg = segments[p];
                                        segments.Remove(p);
                                        segments[s1.Peek()] = seg;
                                    }
                                }
                            }
                            isGroup = false;
                        }


                        if (isGroup)
                        {
                            GroupExpression g = new GroupExpression(contentNode);
                            s1.Push(g);
                        }


                        s2.Pop();
                    }
                    else if (kw.Keyword == ",")
                    {
                        while (s2.Count > 0 && s2.Peek().keywordInfo.Keyword != "(")
                        {
                            s1.Push(GetExpr(s2.Pop(), s1, s2));
                        }
                        var            left = PopData(s1);
                        JoinExpression join;
                        if (s1.Count > 0 && s1.Peek() is JoinExpression)
                        {
                            join = s1.Peek() as JoinExpression;
                        }
                        else
                        {
                            join = new JoinExpression();
                            s1.Push(join);
                        }
                        //join.List.Insert(0, left);
                        join.List.Add(left);
                    }
                    else
                    {
                        if (kw.Keyword == "(")
                        {
                            s1.Push(Expression.Group(Expression.Null));
                        }

                        while (s2.Count > 0 && kw.Priority != 0 && /* s2.Peek().Priority != 0 &&*/ s2.Peek().keywordInfo.Priority > kw.Priority)
                        {
                            var tmp = s2.Pop();
                            s1.Push(GetExpr(tmp, s1, s2));
                        }
                        s2.Push(part);
                    }
                }
                else
                {
                    switch (exprPart.ToLower())
                    {
                    case "true":
                        s1.Push(Expression.True);
                        if (segments != null)
                        {
                            segments[s1.Peek()] = segment;
                        }
                        continue;

                    case "false":
                        s1.Push(Expression.False);
                        if (segments != null)
                        {
                            segments[s1.Peek()] = segment;
                        }
                        continue;

                    case "null":
                        s1.Push(Expression.Null);
                        if (segments != null)
                        {
                            segments[s1.Peek()] = segment;
                        }
                        continue;
                        //case "undefined":
                        //    s1.Push(Expression.Undefined);
                        //    continue;
                    }

                    if (segment.IsDigit)
                    {
                        if (segment.Expr.IndexOf('.') >= 0)
                        {
                            double f;
                            if (double.TryParse(exprPart, out f))
                            {
                                s1.Push(Expression.Constant(f));
                                if (segments != null)
                                {
                                    segments[s1.Peek()] = segment;
                                }
                                continue;
                            }
                        }
                        else
                        {
                            long l;
                            if (long.TryParse(exprPart, out l))
                            {
                                s1.Push(Expression.Constant(l));
                                if (segments != null)
                                {
                                    segments[s1.Peek()] = segment;
                                }
                                continue;
                            }
                        }
                    }


                    if (s2.Count > 0 && s2.Peek().keywordInfo.Keyword == ".")
                    {
                        var variable = s1.Pop();
                        var member   = GetMember(variable, null, exprPart, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.GetField | BindingFlags.GetProperty);
                        if (member == null)
                        {
                            throw new Exception("not found Member :" + exprPart);
                        }
                        if (member.MemberType == MemberTypes.Method)
                        {
                            s1.Push(Expression.Member(variable, null, exprPart));
                            if (segments != null)
                            {
                                segments[s1.Peek()] = segment;
                            }
                        }
                        else
                        {
                            s1.Push(Expression.PropertyOrField(variable, member.Name));
                            if (segments != null)
                            {
                                segments[s1.Peek()] = segment;
                            }
                        }

                        s2.Pop();
                    }

                    else
                    {
                        //variable
                        s1.Push(Expression.Variable(GetVariableType(ctxs, exprPart), exprPart));
                        if (segments != null)
                        {
                            segments[s1.Peek()] = segment;
                        }
                    }
                    //  variables.Push(part);
                }
            }


            while (s2.Count > 0)
            {
                var tmp = s2.Pop();
                s1.Push(GetExpr(tmp, s1, s2));
            }

            result = PopData(s1);



            if (s1.Count > 1)
            {
                throw new Exception("expr stack error, count>1 count:" + s1.Count + ", expr:" + expr + " ,type:" + s1.Peek().ToString());
            }

            PopScope(ctxs);

            //cachedExprs[expr] = result;

            return(result);
        }
Example #39
0
        protected internal override Expression VisitJoin(JoinExpression join)
        {
            if (join.JoinType == JoinType.SingleRowLeftOuterJoin)
            {
                var source = join.Right as SourceWithAliasExpression;

                var hs = allColumnsUsed.TryGetC(source.Alias);

                if (hs == null || hs.Count == 0)
                    return Visit(join.Left);
            }

            if (join.JoinType == JoinType.OuterApply ||join.JoinType == JoinType.LeftOuterJoin)
            {
                var sql = join.Right as SelectExpression;

                if (sql != null && sql.IsOneRow())
                {
                    var hs = allColumnsUsed.TryGetC(sql.Alias);
                    if (hs == null || hs.Count == 0)
                        return Visit(join.Left);
                }
            }

            // visit join in reverse order
            Expression condition = this.Visit(join.Condition);
            SourceExpression right = this.VisitSource(join.Right);
            SourceExpression left = this.VisitSource(join.Left);
            if (left != join.Left || right != join.Right || condition != join.Condition)
            {
                return new JoinExpression(join.JoinType, left, right, condition);
            }
            return join;
        }
Example #40
0
        protected override Expression VisitJoin(JoinExpression join)
        {
            this.VisitSource(join.Left);
            this.AppendNewLine(Indentation.Same);
            switch (join.Join)
            {
                case JoinType.CrossJoin:
                    sb.Append("CROSS JOIN ");
                    break;
                case JoinType.InnerJoin:
                    sb.Append("INNER JOIN ");
                    break;
                case JoinType.CrossApply:
                    sb.Append("CROSS APPLY ");
                    break;
                case JoinType.OuterApply:
                    sb.Append("OUTER APPLY ");
                    break;
                case JoinType.LeftOuter:
                    sb.Append("LEFT OUTER JOIN ");
                    break;
            }
            this.VisitSource(join.Right);
            if (join.Condition != null)
            {
                this.AppendNewLine(Indentation.Inner);
                sb.Append("ON ");

                var binaryExpr = join.Condition as BinaryExpression;

                if (binaryExpr != null
                    && binaryExpr.Left.NodeType == ExpressionType.New
                    && binaryExpr.Right.NodeType == ExpressionType.New)
                {
                    var leftNew = binaryExpr.Left as NewExpression;
                    var rightNew = binaryExpr.Right as NewExpression;

                    if (leftNew.Arguments.Count != rightNew.Arguments.Count)
                        throw new Exception("Anonymous types in join clauses must have the same number of arguments.");

                    for (int i = 0; i < leftNew.Arguments.Count; i++)
                    {
                        if (i != 0)
                            sb.Append(" AND ");

                        this.VisitPredicate(BinaryExpression.Equal(leftNew.Arguments[i], rightNew.Arguments[i]));

                        sb.Append(" ");
                    }
                }
                else
                {
                    this.VisitPredicate(join.Condition);
                }

                this.Indent(Indentation.Outer);
            }
            return join;
        }
Example #41
0
 protected virtual Expression VisitJoin(JoinExpression join)
 {
     var left = this.VisitSource(join.Left);
     var right = this.VisitSource(join.Right);
     var condition = this.Visit(join.Condition);
     return this.UpdateJoin(join, join.Join, left, right, condition);
 }
Example #42
0
 protected JoinExpression UpdateJoin(JoinExpression join, JoinType joinType, Expression left, Expression right, Expression condition)
 {
     if (joinType != join.Join || left != join.Left || right != join.Right || condition != join.Condition)
     {
         return new JoinExpression(joinType, left, right, condition);
     }
     return join;
 }
 protected virtual Expression BindJoin(Type resultType, Expression outerSource, Expression innerSource, LambdaExpression outerKey, LambdaExpression innerKey, LambdaExpression resultSelector)
 {
     ProjectionExpression outerProjection = this.VisitSequence(outerSource);
     ProjectionExpression innerProjection = this.VisitSequence(innerSource);
     this.map[outerKey.Parameters[0]] = outerProjection.Projector;
     Expression outerKeyExpr = this.Visit(outerKey.Body);
     this.map[innerKey.Parameters[0]] = innerProjection.Projector;
     Expression innerKeyExpr = this.Visit(innerKey.Body);
     this.map[resultSelector.Parameters[0]] = outerProjection.Projector;
     this.map[resultSelector.Parameters[1]] = innerProjection.Projector;
     Expression resultExpr = this.Visit(resultSelector.Body);
     JoinExpression join = new JoinExpression(JoinType.InnerJoin, outerProjection.Select, innerProjection.Select, outerKeyExpr.Equal(innerKeyExpr));
     var alias = this.GetNextAlias();
     ProjectedColumns pc = this.ProjectColumns(resultExpr, alias, outerProjection.Select.Alias, innerProjection.Select.Alias);
     return new ProjectionExpression(
         new SelectExpression(alias, pc.Columns, join, null),
         pc.Projector
         );
 }
Example #44
0
        protected override Expression VisitJoin(JoinExpression join)
        {
            VisitSource(join.Left);
            switch (join.Join)
            {
                case JoinType.CrossJoin:
                    sb.Append("CROSS JOIN ");
                    break;
                case JoinType.InnerJoin:
                    sb.Append("INNER JOIN ");
                    break;
                case JoinType.CrossApply:
                    sb.Append("CROSS APPLY ");
                    break;
                case JoinType.OuterApply:
                    sb.Append("OUTER APPLY ");
                    break;
                case JoinType.LeftOuter:
                    sb.Append("LEFT OUTER JOIN ");
                    break;
            }
            VisitSource(join.Right);
            if (join.Condition == null)
            {
                return join;
            }

            sb.Append("ON ");
            VisitPredicate(join.Condition);
            return join;
        }
        protected virtual bool CompareJoin(JoinExpression a, JoinExpression b)
        {
            if (a.Join != b.Join || !this.Compare(a.Left, b.Left))
                return false;

            if (a.Join == JoinType.CrossApply || a.Join == JoinType.OuterApply)
            {
                var save = this.aliasScope;
                try
                {
                    this.aliasScope = new ScopedDictionary<TableAlias, TableAlias>(this.aliasScope);
                    this.MapAliases(a.Left, b.Left);

                    return this.Compare(a.Right, b.Right)
                        && this.Compare(a.Condition, b.Condition);
                }
                finally
                {
                    this.aliasScope = save;
                }
            }
            else
            {
                return this.Compare(a.Right, b.Right)
                    && this.Compare(a.Condition, b.Condition);
            }
        }
        public Expression Bind(PipelineExpression pipeline, PipelineBindingContext bindingContext, MethodCallExpression node, IEnumerable <Expression> arguments)
        {
            var args   = arguments.ToList();
            var joined = bindingContext.Bind(args[0]) as CollectionExpression;

            if (joined == null)
            {
                throw new NotSupportedException("The joined collection cannot have any qualifiers.");
            }

            var sourceKeySelectorLambda = ExpressionHelper.GetLambda(args[1]);

            bindingContext.AddExpressionMapping(sourceKeySelectorLambda.Parameters[0], pipeline.Projector);
            var sourceKeySelector = bindingContext.Bind(sourceKeySelectorLambda.Body) as IFieldExpression;

            if (sourceKeySelector == null)
            {
                var message = string.Format("Unable to determine the serialization information for the outer key selector in the tree: {0}", node.ToString());
                throw new NotSupportedException(message);
            }

            var joinedArraySerializer = joined.Serializer as IBsonArraySerializer;
            BsonSerializationInfo joinedItemSerializationInfo;

            if (joinedArraySerializer == null || !joinedArraySerializer.TryGetItemSerializationInfo(out joinedItemSerializationInfo))
            {
                var message = string.Format("Unable to determine the serialization information for the inner collection: {0}", node.ToString());
                throw new NotSupportedException(message);
            }

            var joinedKeySelectorLambda = ExpressionHelper.GetLambda(args[2]);
            var joinedDocument          = new DocumentExpression(joinedItemSerializationInfo.Serializer);

            bindingContext.AddExpressionMapping(joinedKeySelectorLambda.Parameters[0], joinedDocument);
            var joinedKeySelector = bindingContext.Bind(joinedKeySelectorLambda.Body) as IFieldExpression;

            if (joinedKeySelector == null)
            {
                var message = string.Format("Unable to determine the serialization information for the inner key selector in the tree: {0}", node.ToString());
                throw new NotSupportedException(message);
            }

            var resultSelectorLambda = ExpressionHelper.GetLambda(args[3]);

            var sourceSerializer = pipeline.Projector.Serializer;
            var joinedSerializer = node.Method.Name == "GroupJoin" ?
                                   joined.Serializer :
                                   joinedItemSerializationInfo.Serializer;
            var sourceDocument = new DocumentExpression(sourceSerializer);
            var joinedField    = new FieldExpression(
                resultSelectorLambda.Parameters[1].Name,
                joinedSerializer);

            bindingContext.AddExpressionMapping(
                resultSelectorLambda.Parameters[0],
                sourceDocument);
            bindingContext.AddExpressionMapping(
                resultSelectorLambda.Parameters[1],
                joinedField);
            var resultSelector = bindingContext.Bind(resultSelectorLambda.Body);

            Expression source;

            if (node.Method.Name == "GroupJoin")
            {
                source = new GroupJoinExpression(
                    node.Type,
                    pipeline.Source,
                    joined,
                    (Expression)sourceKeySelector,
                    (Expression)joinedKeySelector,
                    resultSelectorLambda.Parameters[1].Name);
            }
            else
            {
                source = new JoinExpression(
                    node.Type,
                    pipeline.Source,
                    joined,
                    (Expression)sourceKeySelector,
                    (Expression)joinedKeySelector,
                    resultSelectorLambda.Parameters[1].Name);
            }

            SerializationExpression projector;
            var newResultSelector = resultSelector as NewExpression;

            if (newResultSelector != null &&
                newResultSelector.Arguments[0] == sourceDocument &&
                newResultSelector.Arguments[1] == joinedField)
            {
                Func <object, object, object> creator = (s, j) => Activator.CreateInstance(resultSelector.Type, s, j);
                var serializer = (IBsonSerializer)Activator.CreateInstance(
                    typeof(JoinSerializer <>).MakeGenericType(resultSelector.Type),
                    sourceSerializer,
                    newResultSelector.Members[0].Name,
                    joinedSerializer,
                    newResultSelector.Members[1].Name,
                    resultSelectorLambda.Parameters[1].Name,
                    creator);

                projector = new DocumentExpression(serializer);
            }
            else
            {
                projector = bindingContext.BindProjector(ref resultSelector);
                source    = new SelectExpression(
                    source,
                    "__i", // since this is a top-level pipeline, this doesn't matter
                    resultSelector);
            }

            return(new PipelineExpression(
                       source,
                       projector));
        }
        private SelectExpression GetCountSelectExpression(SelectExpression select)
        {
            BinaryExpression binaryExpression = select.Where as BinaryExpression;

            if (binaryExpression != null)
            {
                ScalarExpression scalarExpression = binaryExpression.Left as ScalarExpression;

                if (scalarExpression != null)
                {
                    SelectExpression selectCount = scalarExpression.Select as SelectExpression;

                    if (selectCount != null && selectCount.Columns.Count == 1)
                    {
                        AggregateExpression aggregateExpression = (AggregateExpression)selectCount.Columns[0].Expression;

                        if (aggregateExpression != null && aggregateExpression.AggregateName == "Count")
                        {
                            BinaryExpression where = selectCount.Where as BinaryExpression;

                            if (where != null)
                            {
                                ColumnExpression columnExpression = where.Left as ColumnExpression;

                                if (columnExpression != null)
                                {
                                    TableAlias      tableAlias      = new TableAlias();
                                    TableExpression tableExpression = (TableExpression)select.From;
                                    tableExpression = new TableExpression(tableAlias, tableExpression.Entity, tableExpression.Name);

                                    columnExpression = new ColumnExpression(columnExpression.Type, columnExpression.QueryType, tableAlias, columnExpression.Name);
                                    ColumnDeclaration columnDeclaration = new ColumnDeclaration(string.Empty, columnExpression, columnExpression.QueryType);

                                    BinaryExpression where2 = Expression.MakeBinary(where.NodeType, where.Left, columnExpression);
                                    selectCount = new SelectExpression(selectCount.Alias, selectCount.Columns, selectCount.From, where2);

                                    List <ColumnDeclaration> columns = new List <ColumnDeclaration> {
                                        new ColumnDeclaration("CountValue", new ScalarExpression(selectCount.Columns[0].Expression.Type, selectCount), selectCount.Columns[0].QueryType),
                                        columnDeclaration
                                    };

                                    selectCount = new SelectExpression(tableAlias,
                                                                       columns.ToReadOnly(),
                                                                       tableExpression,
                                                                       null,
                                                                       selectCount.OrderBy,
                                                                       null,
                                                                       selectCount.IsDistinct,
                                                                       selectCount.Skip,
                                                                       selectCount.Take,
                                                                       selectCount.IsReverse);

                                    ColumnExpression countValueColumnExpression = new ColumnExpression(selectCount.Columns[0].Expression.Type,
                                                                                                       selectCount.Columns[0].QueryType,
                                                                                                       tableAlias,
                                                                                                       "CountValue");

                                    SelectExpression newSelect = new SelectExpression(select.Alias,
                                                                                      select.Columns,
                                                                                      select.From,
                                                                                      null,
                                                                                      select.OrderBy,
                                                                                      select.GroupBy,
                                                                                      select.IsDistinct,
                                                                                      select.Skip,
                                                                                      select.Take,
                                                                                      select.IsReverse);

                                    JoinExpression joinExpression = new JoinExpression(JoinType.InnerJoin,
                                                                                       newSelect, selectCount,
                                                                                       Expression.MakeBinary(ExpressionType.Equal, columnExpression, where.Right));

                                    select = new SelectExpression(newSelect.Alias,
                                                                  newSelect.Columns,
                                                                  joinExpression,
                                                                  Expression.MakeBinary(binaryExpression.NodeType, countValueColumnExpression, binaryExpression.Right),
                                                                  newSelect.OrderBy,
                                                                  newSelect.GroupBy,
                                                                  newSelect.IsDistinct,
                                                                  newSelect.Skip,
                                                                  newSelect.Take,
                                                                  newSelect.IsReverse);

                                    return(select);
                                }
                            }
                        }
                    }
                }
            }

            return(null);
        }
Example #48
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     if (join.Join == JoinType.CrossJoin)
     {
         this.VisitJoinLeft(join.Left);
         this.Append(", ");
         this.VisitJoinRight(join.Right);
         return join;
     }
     return base.VisitJoin(join);
 }
Example #49
0
 public void Compile(JoinExpression query)
 {
 }
Example #50
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     expressions.Add(join);
     return(base.VisitJoin(join));
 }
Example #51
0
        public static ISelectStatement FullJoin(this ISelectStatement select, ITableExpression table, IFilterExpression on)
        {
            IJoinExpression join = new JoinExpression(Operator.FullJoin, table, on);

            return(Join(select, join));
        }
 public Expression VisitJoin(JoinExpression expression)
 {
     JoinVisited = true;
     return(expression);
 }
Example #53
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     this.VisitJoinLeft(join.Left);
     this.WriteLine(Indentation.Same);
     switch (join.Join)
     {
         case JoinType.CrossJoin:
             this.Write("CROSS JOIN ");
             break;
         case JoinType.InnerJoin:
             this.Write("INNER JOIN ");
             break;
         case JoinType.CrossApply:
             this.Write("CROSS APPLY ");
             break;
         case JoinType.OuterApply:
             this.Write("OUTER APPLY ");
             break;
         case JoinType.LeftOuter:
         case JoinType.SingletonLeftOuter:
             this.Write("LEFT OUTER JOIN ");
             break;
     }
     this.VisitJoinRight(join.Right);
     if (join.Condition != null)
     {
         this.WriteLine(Indentation.Inner);
         this.Write("ON ");
         this.VisitPredicate(join.Condition);
         this.Indent(Indentation.Outer);
     }
     return join;
 }
Example #54
0
        protected override Expression VisitJoin(JoinExpression join)
        {
            SourceExpression left = this.VisitSource(join.Left);

            ReadOnlyCollection<OrderExpression> leftOrders = this.gatheredOrderings;
            this.gatheredOrderings = null;

            SourceExpression right = join.Right is TableExpression ? join.Right : this.VisitSource(join.Right);

            this.PrependOrderings(leftOrders);

            Expression condition = this.Visit(join.Condition);

            if (left != join.Left || right != join.Right || condition != join.Condition)
            {
                return new JoinExpression(join.JoinType, left, right, condition);
            }
            return join;
        }
Example #55
0
        public static ISelectStatement Join(this ISelectStatement select, ITableExpression table, IFilterExpression on, IJoinOperator joinOperator)
        {
            IJoinExpression join = new JoinExpression(joinOperator, table, on);

            return(Join(select, join));
        }
 protected internal override Expression VisitJoin(JoinExpression join)
 {
     SourceExpression left = this.VisitSource(join.Left);
     SourceExpression right = this.VisitSource(join.Right);
     Expression condition = MakeSqlCondition(this.Visit(join.Condition));
     if (left != join.Left || right != join.Right || condition != join.Condition)
     {
         return new JoinExpression(join.JoinType, left, right, condition);
     }
     return join;
 }