protected override Provider VisitJoin(JoinProvider provider)
        {
            // split

            List <int> leftMapping;
            List <int> rightMapping;

            SplitMappings(provider, out leftMapping, out rightMapping);

            leftMapping  = Merge(leftMapping, provider.EqualIndexes.Select(p => p.First));
            rightMapping = Merge(rightMapping, provider.EqualIndexes.Select(p => p.Second));

            var newLeftProvider  = provider.Left;
            var newRightProvider = provider.Right;

            VisitJoin(ref leftMapping, ref newLeftProvider, ref rightMapping, ref newRightProvider);

            mappings[provider] = MergeMappings(provider.Left, leftMapping, rightMapping);

            if (newLeftProvider == provider.Left && newRightProvider == provider.Right)
            {
                return(provider);
            }

            var newIndexes = new List <Pair <int> >();

            foreach (var pair in provider.EqualIndexes)
            {
                var newLeftIndex  = leftMapping.IndexOf(pair.First);
                var newRightIndex = rightMapping.IndexOf(pair.Second);
                newIndexes.Add(new Pair <int>(newLeftIndex, newRightIndex));
            }
            return(new JoinProvider(newLeftProvider, newRightProvider, provider.JoinType, newIndexes.ToArray()));
        }
Exemplo n.º 2
0
        protected override Provider VisitJoin(JoinProvider provider)
        {
            var left       = VisitCompilable(provider.Left);
            var leftOrder  = sortOrder;
            var right      = VisitCompilable(provider.Right);
            var rightOrder = sortOrder;
            var result     = left == provider.Left && right == provider.Right
        ? provider
        : new JoinProvider(left, right, provider.JoinType, provider.EqualIndexes);

            sortOrder = ComputeBinaryOrder(provider, leftOrder, rightOrder);
            return(result);
        }
        protected override Provider VisitJoin(JoinProvider provider)
        {
            CompilableProvider left;
            CompilableProvider right;

            VisitBinaryProvider(provider, out left, out right);

            if (provider.JoinType == JoinType.LeftOuter)
            {
                EnsureAbsenceOfApplyProviderRequiringConversion();
            }

            if (left != provider.Left || right != provider.Right)
            {
                return(new JoinProvider(left, right, provider.JoinType, provider.EqualIndexes));
            }
            return(provider);
        }
Exemplo n.º 4
0
 private SqlExpression GetJoinExpression(SqlExpression leftExpression, SqlExpression rightExpression, JoinProvider provider, int index)
 {
     if (provider.EqualColumns.Length > index)
     {
         if (providerInfo.Supports(ProviderFeatures.DateTimeEmulation))
         {
             if (provider.EqualColumns[index].First.Type == typeof(DateTime))
             {
                 leftExpression = SqlDml.Cast(leftExpression, SqlType.DateTime);
             }
             if (provider.EqualColumns[index].Second.Type == typeof(DateTime))
             {
                 rightExpression = SqlDml.Cast(rightExpression, SqlType.DateTime);
             }
         }
         if (providerInfo.Supports(ProviderFeatures.DateTimeOffsetEmulation))
         {
             if (provider.EqualColumns[index].First.Type == typeof(DateTimeOffset))
             {
                 leftExpression = SqlDml.Cast(leftExpression, SqlType.DateTimeOffset);
             }
             if (provider.EqualColumns[index].Second.Type == typeof(DateTimeOffset))
             {
                 rightExpression = SqlDml.Cast(rightExpression, SqlType.DateTimeOffset);
             }
         }
     }
     return(leftExpression == rightExpression);
 }
Exemplo n.º 5
0
 /// <summary>
 /// Compiles <see cref="JoinProvider"/>.
 /// </summary>
 /// <param name="provider">Join provider.</param>
 protected abstract TResult VisitJoin(JoinProvider provider);
Exemplo n.º 6
0
        /// <inheritdoc/>
        protected override SqlProvider VisitJoin(JoinProvider provider)
        {
            var left  = Compile(provider.Left);
            var right = Compile(provider.Right);

            // SQLite does not allow certain join combinations
            // Any right part of join expression should not be join itself
            // See IssueA363_WrongInnerJoin for example of such query

            var strictJoinWorkAround =
                providerInfo.Supports(ProviderFeatures.StrictJoinSyntax) &&
                right.Request.Statement.From is SqlJoinedTable;

            var leftShouldUseReference = ShouldUseQueryReference(provider, left);
            var leftTable = leftShouldUseReference
        ? left.PermanentReference
        : left.Request.Statement.From;
            var leftColumns = leftShouldUseReference
        ? leftTable.Columns.Cast <SqlColumn>()
        : left.Request.Statement.Columns;
            var leftExpressions = leftShouldUseReference
        ? leftTable.Columns.Cast <SqlExpression>().ToList()
        : ExtractColumnExpressions(left.Request.Statement);

            var rightShouldUseReference = strictJoinWorkAround || ShouldUseQueryReference(provider, right);
            var rightTable = rightShouldUseReference
        ? right.PermanentReference
        : right.Request.Statement.From;
            var rightColumns = rightShouldUseReference
        ? rightTable.Columns.Cast <SqlColumn>()
        : right.Request.Statement.Columns;
            var rightExpressions = rightShouldUseReference
        ? rightTable.Columns.Cast <SqlExpression>().ToList()
        : ExtractColumnExpressions(right.Request.Statement);

            var joinType = provider.JoinType == JoinType.LeftOuter
        ? SqlJoinType.LeftOuterJoin
        : SqlJoinType.InnerJoin;

            SqlExpression joinExpression = null;

            for (var i = 0; i < provider.EqualIndexes.Count(); ++i)
            {
                var leftExpression  = leftExpressions[provider.EqualIndexes[i].First];
                var rightExpression = rightExpressions[provider.EqualIndexes[i].Second];
                joinExpression &= GetJoinExpression(leftExpression, rightExpression, provider, i);
            }

            var joinedTable = SqlDml.Join(
                joinType,
                leftTable,
                rightTable,
                leftColumns.ToList(),
                rightColumns.ToList(),
                joinExpression);

            var query = SqlDml.Select(joinedTable);

            if (!leftShouldUseReference)
            {
                query.Where &= left.Request.Statement.Where;
            }
            if (!rightShouldUseReference)
            {
                query.Where &= right.Request.Statement.Where;
            }
            query.Columns.AddRange(joinedTable.AliasedColumns);
            return(CreateProvider(query, provider, left, right));
        }