Exemple #1
0
        private void Map(List <SortKey> sortKeys)
        {
            VarVec varVec = this.m_command.CreateVarVec();
            bool   flag   = false;

            foreach (SortKey sortKey in sortKeys)
            {
                sortKey.Var = this.Map(sortKey.Var);
                if (varVec.IsSet(sortKey.Var))
                {
                    flag = true;
                }
                varVec.Set(sortKey.Var);
            }
            if (!flag)
            {
                return;
            }
            List <SortKey> sortKeyList = new List <SortKey>((IEnumerable <SortKey>)sortKeys);

            sortKeys.Clear();
            varVec.Clear();
            foreach (SortKey sortKey in sortKeyList)
            {
                if (!varVec.IsSet(sortKey.Var))
                {
                    sortKeys.Add(sortKey);
                }
                varVec.Set(sortKey.Var);
            }
        }
Exemple #2
0
        private static bool IsEquiJoinPredicate(
            System.Data.Entity.Core.Query.InternalTrees.Node simplePredicateNode,
            VarVec leftTableDefinitions,
            VarVec rightTableDefinitions,
            out Var leftVar,
            out Var rightVar)
        {
            leftVar  = (Var)null;
            rightVar = (Var)null;
            Var leftVar1;
            Var rightVar1;

            if (!Predicate.IsEquiJoinPredicate(simplePredicateNode, out leftVar1, out rightVar1))
            {
                return(false);
            }
            if (leftTableDefinitions.IsSet(leftVar1) && rightTableDefinitions.IsSet(rightVar1))
            {
                leftVar  = leftVar1;
                rightVar = rightVar1;
            }
            else
            {
                if (!leftTableDefinitions.IsSet(rightVar1) || !rightTableDefinitions.IsSet(leftVar1))
                {
                    return(false);
                }
                leftVar  = rightVar1;
                rightVar = leftVar1;
            }
            return(true);
        }
        /// <summary>
        /// Is this an equi-join predicate involving columns from the specified tables?
        /// On output, if this was indeed an equijoin predicate, "leftVar" is the
        /// column of the left table, while "rightVar" is the column of the right table
        /// and the predicate itself is of the form "leftVar = rightVar"
        /// </summary>
        /// <param name="simplePredicateNode">the simple predicate node</param>
        /// <param name="leftTableDefinitions">interesting columns of the left table</param>
        /// <param name="rightTableDefinitions">interesting columns of the right table</param>
        /// <param name="leftVar">join column of the left table</param>
        /// <param name="rightVar">join column of the right table</param>
        /// <returns>true, if this is an equijoin predicate involving columns from the 2 tables</returns>
        private static bool IsEquiJoinPredicate(Node simplePredicateNode,
                                                VarVec leftTableDefinitions, VarVec rightTableDefinitions,
                                                out Var leftVar, out Var rightVar)
        {
            Var tempLeftVar;
            Var tempRightVar;

            leftVar  = null;
            rightVar = null;
            if (!Predicate.IsEquiJoinPredicate(simplePredicateNode, out tempLeftVar, out tempRightVar))
            {
                return(false);
            }

            if (leftTableDefinitions.IsSet(tempLeftVar) &&
                rightTableDefinitions.IsSet(tempRightVar))
            {
                leftVar  = tempLeftVar;
                rightVar = tempRightVar;
            }
            else if (leftTableDefinitions.IsSet(tempRightVar) &&
                     rightTableDefinitions.IsSet(tempLeftVar))
            {
                leftVar  = tempRightVar;
                rightVar = tempLeftVar;
            }
            else
            {
                return(false);
            }

            return(true);
        }
Exemple #4
0
        // <summary>
        // Does this predicate preserve nulls on the specified columns of the table?
        // If any of the columns participates in a comparison predicate, or in a
        // not-null predicate, then, nulls are not preserved
        // </summary>
        // <param name="simplePredNode"> the "simple" predicate node </param>
        // <param name="tableColumns"> list of table columns </param>
        // <returns> true, if nulls are preserved </returns>
        private static bool PreservesNulls(Node simplePredNode, VarVec tableColumns)
        {
            VarRefOp varRefOp;

            switch (simplePredNode.Op.OpType)
            {
            case OpType.EQ:
            case OpType.NE:
            case OpType.GT:
            case OpType.GE:
            case OpType.LT:
            case OpType.LE:
                varRefOp = simplePredNode.Child0.Op as VarRefOp;
                if (varRefOp != null &&
                    tableColumns.IsSet(varRefOp.Var))
                {
                    return(false);
                }
                varRefOp = simplePredNode.Child1.Op as VarRefOp;
                if (varRefOp != null &&
                    tableColumns.IsSet(varRefOp.Var))
                {
                    return(false);
                }
                return(true);

            case OpType.Not:
                if (simplePredNode.Child0.Op.OpType
                    != OpType.IsNull)
                {
                    return(true);
                }
                varRefOp = simplePredNode.Child0.Child0.Op as VarRefOp;
                return(varRefOp == null || !tableColumns.IsSet(varRefOp.Var));

            case OpType.Like:
                // If the predicate is "column LIKE constant ...", then the
                // predicate does not preserve nulls
                var constantOp = simplePredNode.Child1.Op as ConstantBaseOp;
                if (constantOp == null ||
                    (constantOp.OpType == OpType.Null))
                {
                    return(true);
                }
                varRefOp = simplePredNode.Child0.Op as VarRefOp;
                if (varRefOp != null &&
                    tableColumns.IsSet(varRefOp.Var))
                {
                    return(false);
                }
                return(true);

            default:
                return(true);
            }
        }
Exemple #5
0
        private void RemoveRedundantConstantKeys(VarVec keyVec, VarVec outputVec, System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode)
        {
            List <System.Data.Entity.Core.Query.InternalTrees.Node> constantKeys = varDefListNode.Children.Where <System.Data.Entity.Core.Query.InternalTrees.Node>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, bool>)(d =>
            {
                if (d.Op.OpType == OpType.VarDef)
                {
                    return(PlanCompilerUtil.IsConstantBaseOp(d.Child0.Op.OpType));
                }
                return(false);
            })).ToList <System.Data.Entity.Core.Query.InternalTrees.Node>();
            VarVec constantKeyVars = this.m_command.CreateVarVec(constantKeys.Select <System.Data.Entity.Core.Query.InternalTrees.Node, Var>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, Var>)(d => ((VarDefOp)d.Op).Var)));

            constantKeyVars.Minus(this.m_referencedVars);
            keyVec.Minus(constantKeyVars);
            outputVec.Minus(constantKeyVars);
            varDefListNode.Children.RemoveAll((Predicate <System.Data.Entity.Core.Query.InternalTrees.Node>)(c =>
            {
                if (constantKeys.Contains(c))
                {
                    return(constantKeyVars.IsSet(((VarDefOp)c.Op).Var));
                }
                return(false);
            }));
            if (keyVec.Count != 0)
            {
                return;
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node = constantKeys.First <System.Data.Entity.Core.Query.InternalTrees.Node>();
            Var var = ((VarDefOp)node.Op).Var;

            keyVec.Set(var);
            outputVec.Set(var);
            varDefListNode.Children.Add(node);
        }
Exemple #6
0
        private bool IsKeyPredicate(Node left, Node right, VarVec keyVars, VarVec definitions, out Var keyVar)
        {
            keyVar = null;

            // If the left-side is not a Var, then return false
            if (left.Op.OpType
                != OpType.VarRef)
            {
                return(false);
            }
            var varRefOp = (VarRefOp)left.Op;

            keyVar = varRefOp.Var;

            // Not a key of this table?
            if (!keyVars.IsSet(keyVar))
            {
                return(false);
            }

            // Make sure that the other side is either a constant, or has no
            // references at all to us
            var otherNodeInfo = m_command.GetNodeInfo(right);
            var otherVarExternalReferences = otherNodeInfo.ExternalReferences.Clone();

            otherVarExternalReferences.And(definitions);
            return(otherVarExternalReferences.IsEmpty);
        }
        /// <summary>
        /// Helper method for removing redundant constant keys from GroupByOp and DistictOp.
        /// It only examines the keys defined in the given varDefListNode.
        /// It removes all constant and null keys that are not referenced elsewhere,
        /// but ensuring that at least one key is left.
        /// It should not be called with empty keyVec.
        /// </summary>
        /// <param name="keyVec">The keys</param>
        /// <param name="outputVec">The var vec that needs to be updated along with the keys</param>
        /// <param name="varDefListNode">Var def list node for the keys </param>
        private void RemoveRedundantConstantKeys(VarVec keyVec, VarVec outputVec, Node varDefListNode)
        {
            //Find all the keys that are nulls and constants
            List <Node> constantKeys = varDefListNode.Children.Where(d => d.Op.OpType == OpType.VarDef &&
                                                                     PlanCompilerUtil.IsConstantBaseOp(d.Child0.Op.OpType)).ToList();

            VarVec constantKeyVars = this.m_command.CreateVarVec(constantKeys.Select(d => ((VarDefOp)d.Op).Var));

            //Get the list of unreferenced  constant keys
            constantKeyVars.Minus(m_referencedVars);

            //Remove the unreferenced constant keys
            keyVec.Minus(constantKeyVars);
            outputVec.Minus(constantKeyVars);

            varDefListNode.Children.RemoveAll(c => constantKeys.Contains(c) && constantKeyVars.IsSet(((VarDefOp)c.Op).Var));

            //If no keys are left add one.
            if (keyVec.Count == 0)
            {
                Node keyNode = constantKeys.First();
                Var  keyVar  = ((VarDefOp)keyNode.Op).Var;
                keyVec.Set(keyVar);
                outputVec.Set(keyVar);
                varDefListNode.Children.Add(keyNode);
            }
        }
Exemple #8
0
        private static bool PreservesNulls(System.Data.Entity.Core.Query.InternalTrees.Node simplePredNode, VarVec tableColumns)
        {
            switch (simplePredNode.Op.OpType)
            {
            case OpType.GT:
            case OpType.GE:
            case OpType.LE:
            case OpType.LT:
            case OpType.EQ:
            case OpType.NE:
                VarRefOp op1 = simplePredNode.Child0.Op as VarRefOp;
                if (op1 != null && tableColumns.IsSet(op1.Var))
                {
                    return(false);
                }
                VarRefOp op2 = simplePredNode.Child1.Op as VarRefOp;
                return(op2 == null || !tableColumns.IsSet(op2.Var));

            case OpType.Like:
                ConstantBaseOp op3 = simplePredNode.Child1.Op as ConstantBaseOp;
                if (op3 == null || op3.OpType == OpType.Null)
                {
                    return(true);
                }
                VarRefOp op4 = simplePredNode.Child0.Op as VarRefOp;
                return(op4 == null || !tableColumns.IsSet(op4.Var));

            case OpType.Not:
                if (simplePredNode.Child0.Op.OpType != OpType.IsNull)
                {
                    return(true);
                }
                VarRefOp op5 = simplePredNode.Child0.Child0.Op as VarRefOp;
                if (op5 != null)
                {
                    return(!tableColumns.IsSet(op5.Var));
                }
                return(true);

            default:
                return(true);
            }
        }
 // <summary>
 // Does the given list of sort keys contain a key with a var that is the given VarVec
 // </summary>
 private static bool HasVarReferences(List <SortKey> listToCheck, VarVec vars)
 {
     foreach (var key in listToCheck)
     {
         if (vars.IsSet(key.Var))
         {
             return(true);
         }
     }
     return(false);
 }
 // <summary>
 // Does the list of outputs of the given SetOp contain a var
 // from the given VarVec defined by the SetOp's child with the given index
 // </summary>
 private static bool HasVarReferences(SetOp op, VarVec vars, int index)
 {
     foreach (var var in op.VarMap[index].Values)
     {
         if (vars.IsSet(var))
         {
             return(true);
         }
     }
     return(false);
 }
        private void Map(List <InternalTrees.SortKey> sortKeys)
        {
            VarVec sortVars      = m_command.CreateVarVec();
            bool   hasDuplicates = false;

            //
            // Map each var in the sort list. Remapping may introduce duplicates, and
            // we should get rid of duplicates, since sql doesn't like them
            //
            foreach (InternalTrees.SortKey sk in sortKeys)
            {
                sk.Var = Map(sk.Var);
                if (sortVars.IsSet(sk.Var))
                {
                    hasDuplicates = true;
                }
                sortVars.Set(sk.Var);
            }

            //
            // Get rid of any duplicates
            //
            if (hasDuplicates)
            {
                List <InternalTrees.SortKey> newSortKeys = new List <SortKey>(sortKeys);
                sortKeys.Clear();
                sortVars.Clear();
                foreach (InternalTrees.SortKey sk in newSortKeys)
                {
                    if (!sortVars.IsSet(sk.Var))
                    {
                        sortKeys.Add(sk);
                    }
                    sortVars.Set(sk.Var);
                }
            }
        }
Exemple #12
0
            public override void Visit(VarRefOp op, Node n)
            {
                var referencedVar = op.Var;

                if (m_varVec.IsSet(referencedVar))
                {
                    if (m_usedVars.IsSet(referencedVar))
                    {
                        m_anyUsedMoreThenOnce = true;
                    }
                    else
                    {
                        m_usedVars.Set(referencedVar);
                    }
                }
            }
Exemple #13
0
        private bool IsKeyPredicate(
            System.Data.Entity.Core.Query.InternalTrees.Node left,
            System.Data.Entity.Core.Query.InternalTrees.Node right,
            VarVec keyVars,
            VarVec definitions,
            out Var keyVar)
        {
            keyVar = (Var)null;
            if (left.Op.OpType != OpType.VarRef)
            {
                return(false);
            }
            VarRefOp op = (VarRefOp)left.Op;

            keyVar = op.Var;
            if (!keyVars.IsSet(keyVar))
            {
                return(false);
            }
            VarVec varVec = this.m_command.GetNodeInfo(right).ExternalReferences.Clone();

            varVec.And(definitions);
            return(varVec.IsEmpty);
        }
        // <summary>
        // Callback function to invoke *before* rules are applied.
        // Calls the VarRemapper to update any Vars in the entire subtree
        // If the given node has a RelOp it is pushed on the relOp ancestors stack.
        // </summary>
        internal override void PreProcessSubTree(Node subTree)
        {
            if (subTree.Op.IsRelOp)
            {
                m_relOpAncestors.Push(subTree);
            }

            if (m_remappedVars.IsEmpty)
            {
                return;
            }

            var nodeInfo = Command.GetNodeInfo(subTree);

            //We need to do remapping only if m_remappedVars overlaps with nodeInfo.ExternalReferences
            foreach (var v in nodeInfo.ExternalReferences)
            {
                if (m_remappedVars.IsSet(v))
                {
                    m_remapper.RemapSubtree(subTree);
                    break;
                }
            }
        }
 /// <summary>
 ///     Does the given list of sort keys contain a key with a var that is the given VarVec
 /// </summary>
 private static bool HasVarReferences(List<SortKey> listToCheck, VarVec vars)
 {
     foreach (var key in listToCheck)
     {
         if (vars.IsSet(key.Var))
         {
             return true;
         }
     }
     return false;
 }
Exemple #16
0
        // <summary>
        // Is this an equi-join predicate involving columns from the specified tables?
        // On output, if this was indeed an equijoin predicate, "leftVar" is the
        // column of the left table, while "rightVar" is the column of the right table
        // and the predicate itself is of the form "leftVar = rightVar"
        // </summary>
        // <param name="simplePredicateNode"> the simple predicate node </param>
        // <param name="leftTableDefinitions"> interesting columns of the left table </param>
        // <param name="rightTableDefinitions"> interesting columns of the right table </param>
        // <param name="leftVar"> join column of the left table </param>
        // <param name="rightVar"> join column of the right table </param>
        // <returns> true, if this is an equijoin predicate involving columns from the 2 tables </returns>
        private static bool IsEquiJoinPredicate(
            Node simplePredicateNode,
            VarVec leftTableDefinitions, VarVec rightTableDefinitions,
            out Var leftVar, out Var rightVar)
        {
            Var tempLeftVar;
            Var tempRightVar;

            leftVar = null;
            rightVar = null;
            if (!IsEquiJoinPredicate(simplePredicateNode, out tempLeftVar, out tempRightVar))
            {
                return false;
            }

            if (leftTableDefinitions.IsSet(tempLeftVar)
                &&
                rightTableDefinitions.IsSet(tempRightVar))
            {
                leftVar = tempLeftVar;
                rightVar = tempRightVar;
            }
            else if (leftTableDefinitions.IsSet(tempRightVar)
                     &&
                     rightTableDefinitions.IsSet(tempLeftVar))
            {
                leftVar = tempRightVar;
                rightVar = tempLeftVar;
            }
            else
            {
                return false;
            }

            return true;
        }
Exemple #17
0
        // <summary>
        // Does this predicate preserve nulls on the specified columns of the table?
        // If any of the columns participates in a comparison predicate, or in a
        // not-null predicate, then, nulls are not preserved
        // </summary>
        // <param name="simplePredNode"> the "simple" predicate node </param>
        // <param name="tableColumns"> list of table columns </param>
        // <returns> true, if nulls are preserved </returns>
        private static bool PreservesNulls(Node simplePredNode, VarVec tableColumns)
        {
            VarRefOp varRefOp;

            switch (simplePredNode.Op.OpType)
            {
                case OpType.EQ:
                case OpType.NE:
                case OpType.GT:
                case OpType.GE:
                case OpType.LT:
                case OpType.LE:
                    varRefOp = simplePredNode.Child0.Op as VarRefOp;
                    if (varRefOp != null
                        && tableColumns.IsSet(varRefOp.Var))
                    {
                        return false;
                    }
                    varRefOp = simplePredNode.Child1.Op as VarRefOp;
                    if (varRefOp != null
                        && tableColumns.IsSet(varRefOp.Var))
                    {
                        return false;
                    }
                    return true;

                case OpType.Not:
                    if (simplePredNode.Child0.Op.OpType
                        != OpType.IsNull)
                    {
                        return true;
                    }
                    varRefOp = simplePredNode.Child0.Child0.Op as VarRefOp;
                    return (varRefOp == null || !tableColumns.IsSet(varRefOp.Var));

                case OpType.Like:
                    // If the predicate is "column LIKE constant ...", then the
                    // predicate does not preserve nulls
                    var constantOp = simplePredNode.Child1.Op as ConstantBaseOp;
                    if (constantOp == null
                        || (constantOp.OpType == OpType.Null))
                    {
                        return true;
                    }
                    varRefOp = simplePredNode.Child0.Op as VarRefOp;
                    if (varRefOp != null
                        && tableColumns.IsSet(varRefOp.Var))
                    {
                        return false;
                    }
                    return true;

                default:
                    return true;
            }
        }
Exemple #18
0
        private bool IsKeyPredicate(Node left, Node right, VarVec keyVars, VarVec definitions, out Var keyVar)
        {
            keyVar = null;

            // If the left-side is not a Var, then return false
            if (left.Op.OpType
                != OpType.VarRef)
            {
                return false;
            }
            var varRefOp = (VarRefOp)left.Op;
            keyVar = varRefOp.Var;

            // Not a key of this table?
            if (!keyVars.IsSet(keyVar))
            {
                return false;
            }

            // Make sure that the other side is either a constant, or has no
            // references at all to us
            var otherNodeInfo = m_command.GetNodeInfo(right);
            var otherVarExternalReferences = otherNodeInfo.ExternalReferences.Clone();
            otherVarExternalReferences.And(definitions);
            return otherVarExternalReferences.IsEmpty;
        }
 /// <summary>
 ///     Is this Var referenced?
 /// </summary>
 /// <param name="v"> </param>
 /// <returns> </returns>
 private bool IsReferenced(Var v)
 {
     return(m_referencedVars.IsSet(v));
 }
 /// <summary>
 ///     Does the list of outputs of the given SetOp contain a var
 ///     from the given VarVec defined by the SetOp's child with the given index
 /// </summary>
 private static bool HasVarReferences(SetOp op, VarVec vars, int index)
 {
     foreach (var var in op.VarMap[index].Values)
     {
         if (vars.IsSet(var))
         {
             return true;
         }
     }
     return false;
 }