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); } }
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); }
// <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); } }
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); }
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); } }
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); } } }
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); } } }
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; }
// <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; }
// <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; } }
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; }