Example #1
0
 protected InFragment TryMergeTwoBinaryFragments(BinaryFragment left, BinaryFragment right)
 {
     if ((left.IsNegated == right.IsNegated) && (!left.IsNegated) &&
         (left.Operator == "=") && (right.Operator == "="))
     {
         ColumnFragment  cf;
         LiteralFragment lf;
         GetBinaryFragmentPartsForIn(left, out lf, out cf);
         if ((lf != null) && (cf != null))
         {
             ColumnFragment  cf2;
             LiteralFragment lf2;
             GetBinaryFragmentPartsForIn(right, out lf2, out cf2);
             if ((lf2 != null) && (cf2 != null) && cf.Equals(cf2))
             {
                 InFragment inf = new InFragment();
                 inf.Argument = cf;
                 inf.InList.Add(lf);
                 inf.InList.Add(lf2);
                 return(inf);
             }
         }
     }
     return(null);
 }
Example #2
0
 protected void GetBinaryFragmentPartsForIn(BinaryFragment bf, out LiteralFragment lf, out ColumnFragment cf)
 {
     cf = bf.Right as ColumnFragment;
     lf = bf.Left as LiteralFragment;
     if (lf == null)
     {
         lf = bf.Right as LiteralFragment;
         cf = bf.Left as ColumnFragment;
     }
 }
        protected override SqlFragment VisitBinaryExpression(DbExpression left, DbExpression right, string op)
        {
            BinaryFragment f = new BinaryFragment();

            f.Operator = op;
            f.Left     = left.Accept(this);
            f.WrapLeft = ShouldWrapExpression(left);
            if (f.Left is ColumnFragment)
            {
                _columnsVisited.Push((( DbPropertyExpression )left).Property);
            }
            f.Right = right.Accept(this);
            if (f.Left is ColumnFragment)
            {
                _columnsVisited.Pop();
            }
            f.WrapRight = ShouldWrapExpression(right);
            return(f);
        }
Example #4
0
 protected InFragment TryMergeBinaryFragmentAndInFragment(BinaryFragment bf, InFragment inf)
 {
     if (!bf.IsNegated && (bf.Operator == "="))
     {
         ColumnFragment  cf;
         LiteralFragment lf;
         GetBinaryFragmentPartsForIn(bf, out lf, out cf);
         if ((lf != null) && (cf != null))
         {
             if (inf.Argument.Equals(cf))
             {
                 if (!inf.InList.Contains(lf))
                 {
                     inf.InList.Add(lf);
                 }
                 return(inf);
             }
         }
     }
     return(null);
 }
Example #5
0
        protected virtual SqlFragment VisitBinaryExpression(DbExpression left, DbExpression right, string op)
        {
            // Optimization: try to use 'like' instead of 'locate' (Edm.IndexOf) for these
            // cases: (like 'word%'), (like '%word') & (like '%word%').
            LikeFragment like = TryPromoteToLike(left, right, op);

            if (like != null)
            {
                return(like);
            }
            // normal flow
            BinaryFragment f = new BinaryFragment();

            f.Operator  = op;
            f.Left      = left.Accept(this);
            f.WrapLeft  = ShouldWrapExpression(left);
            f.Right     = right.Accept(this);
            f.WrapRight = ShouldWrapExpression(right);
            // Optimization, try to promote to In expression
            // NOTE: In EF6, this optimization is already done, we just implement Visit(DbInExpression).
            return(f);
        }
Example #6
0
 protected virtual SqlFragment TryToPromoteToIn(BinaryFragment bf)
 {
     // TODO: Remember Morgan's theorem
     // Only try to merge if they are OR'ed.
     if ((bf.Operator == "OR"))
     {
         InFragment inf  = bf.Left as InFragment;
         InFragment inf2 = bf.Right as InFragment;
         if (inf == null)
         {
             BinaryFragment bfLeft = bf.Left as BinaryFragment;
             if (bfLeft == null)
             {
                 return(bf);
             }
             if (inf2 == null)
             {
                 // try to create a new infragment
                 BinaryFragment bfRight = bf.Right as BinaryFragment;
                 if (bfRight == null)
                 {
                     return(bf);
                 }
                 InFragment inff = TryMergeTwoBinaryFragments(bfLeft, bfRight);
                 if (inff != null)
                 {
                     return(inff);
                 }
             }
             else
             {
                 // try to merge an existing infragment & a binaryfragment.
                 SqlFragment sf = TryMergeBinaryFragmentAndInFragment(bfLeft, inf2);
                 if (sf != null)
                 {
                     return(sf);
                 }
             }
         }
         else if (inf2 == null)
         {
             BinaryFragment bfRight = bf.Right as BinaryFragment;
             if (bfRight == null)
             {
                 return(bf);
             }
             else
             {
                 // try to merge an existing infragment & a binaryfragment.
                 SqlFragment sf = TryMergeBinaryFragmentAndInFragment(bfRight, inf);
                 if (sf != null)
                 {
                     return(sf);
                 }
             }
         }
         else
         {
             // try to merge both InFragments
             SqlFragment sf = TryMergeTwoInFragments(inf, inf2);
             if (sf != null)
             {
                 return(sf);
             }
         }
     }
     return(bf);
 }
        public override SqlFragment Visit(DbApplyExpression expression)
        {
            DbExpressionBinding inputBinding = expression.Input;
            InputFragment       input        = VisitInputExpression(inputBinding.Expression, inputBinding.VariableName, inputBinding.VariableType);
            DbExpressionBinding applyBinding = expression.Apply;
            InputFragment       apply        = VisitInputExpression(applyBinding.Expression, applyBinding.VariableName, applyBinding.VariableType);
            SelectStatement     select       = new SelectStatement(this);
            bool isInputSelect = false;

            if (!(input is TableFragment))
            {
                input.Wrap(scope);
                isInputSelect = true;
            }
            apply.Wrap(scope);
            select.From = input;
            select.Wrap(scope);
            if (apply is SelectStatement)
            {
                SelectStatement applySel = apply as SelectStatement;
                foreach (ColumnFragment f in applySel.Columns)
                {
                    SelectStatement newColSelect = new SelectStatement(this);
                    newColSelect.From  = applySel.From;
                    newColSelect.Where = applySel.Where;
                    if (isInputSelect)
                    {
                        VisitAndReplaceTableName(newColSelect.Where, (input as SelectStatement).From.Name, input.Name, null);
                    }
                    newColSelect.Limit      = applySel.Limit;
                    newColSelect.OrderBy    = applySel.OrderBy;
                    newColSelect.Skip       = applySel.Skip;
                    newColSelect.GroupBy    = applySel.GroupBy;
                    newColSelect.IsDistinct = applySel.IsDistinct;
                    newColSelect.Columns.Add(f);

                    newColSelect.Wrap(scope);
                    scope.Add(applySel.From.Name, applySel.From);

                    ColumnFragment newCol = new ColumnFragment(apply.Name, f.ColumnName);
                    newCol.Literal = newColSelect;
                    newCol.PushInput(newCol.ColumnName);
                    newCol.PushInput(apply.Name);
                    select.AddColumn(newCol, scope);
                    if (string.IsNullOrEmpty(newCol.ColumnAlias))
                    {
                        newColSelect.Name  = newCol.ColumnName;
                        newCol.ColumnAlias = newCol.ColumnName;
                    }
                    scope.Remove(newColSelect);
                }
                scope.Remove(applySel.From);
                scope.Remove(apply);
            }
            else if (apply is UnionFragment)
            {
                UnionFragment uf = apply as UnionFragment;
                if (uf.Left == null || uf.Right == null)
                {
                    throw new Exception("Union fragment is not properly formed.");
                }

                var left  = uf.Left as SelectStatement;
                var right = uf.Right as SelectStatement;

                if (left == null || right == null)
                {
                    throw new NotImplementedException();
                }

                var whereleft  = left.Where as BinaryFragment;
                var whereright = right.Where as BinaryFragment;

                if (whereleft == null || whereright == null)
                {
                    throw new NotImplementedException();
                }

                LiteralFragment literalFragmentWhere = null;

                //checking where left
                if (whereleft.Left is ColumnFragment && whereleft.Right is ColumnFragment)
                {
                    // we replace the where part for a dummy one
                    if (whereright.Left is ColumnFragment && whereright.Right is ColumnFragment)
                    {
                        literalFragmentWhere = new LiteralFragment("1 = 1");
                    }
                }

                if (literalFragmentWhere == null)
                {
                    throw new NotImplementedException();
                }

                var leftouterjoin = new JoinFragment();
                leftouterjoin.JoinType = Metadata.GetOperator(DbExpressionKind.LeftOuterJoin);
                leftouterjoin.Name     = apply.Name;

                // validating that column fragment on the left matches the name
                // for the input fragment
                var leftColumnFragment = whereleft.Left as ColumnFragment;

                if (leftColumnFragment == null)
                {
                    throw new NotImplementedException();
                }

                if (!leftColumnFragment.TableName.Equals(input.Name))
                {
                    new NotImplementedException();
                }

                var conditionJoin = new BinaryFragment();
                conditionJoin.Left = whereleft.Left;

                //update to the new reference
                var newColumnFragment = whereright.Right as ColumnFragment;
                if (newColumnFragment != null)
                {
                    newColumnFragment.TableName = uf.Name;
                }
                conditionJoin.Right    = newColumnFragment;
                conditionJoin.Operator = whereleft.Operator;

                leftouterjoin.Condition = conditionJoin;

                (uf.Left as SelectStatement).Where  = literalFragmentWhere;
                (uf.Right as SelectStatement).Where = literalFragmentWhere;

                leftouterjoin.Left  = input;
                leftouterjoin.Right = uf;

                return(leftouterjoin);
            }
            return(select);
        }
Example #8
0
 public void Visit(BinaryFragment f)
 {
 }