protected override void VisitSetOp(SetOp op, Node n) { Dictionary <string, object> attrs = new Dictionary <string, object>(); if (OpType.UnionAll == op.OpType) { UnionAllOp uallOp = (UnionAllOp)op; if (null != uallOp.BranchDiscriminator) { attrs.Add("branchDiscriminator", uallOp.BranchDiscriminator); } } using (new AutoXml(this, op, attrs)) { using (new AutoXml(this, "outputs")) { foreach (Var v in op.Outputs) { DumpVar(v); } } int i = 0; foreach (Node chi in n.Children) { Dictionary <string, object> attrs2 = new Dictionary <string, object>(); attrs2.Add("VarMap", op.VarMap[i++].ToString()); using (new AutoXml(this, "input", attrs2)) { VisitNode(chi); } } } }
/// <summary> /// Common copy path for all SetOps /// </summary> /// <param name="op">The SetOp to Copy (must be one of ExceptOp, IntersectOp, UnionAllOp)</param> /// <param name="n">The Node that references the Op</param> /// <returns>A copy of the original Node that references a copy of the original Op</returns> private Node CopySetOp(SetOp op, Node n) { // Visit the Node's children and map their Vars List <Node> children = ProcessChildren(n); VarMap leftMap = new VarMap(); VarMap rightMap = new VarMap(); foreach (KeyValuePair <Var, Var> kv in op.VarMap[0]) { // Create a new output Var that is a copy of the original output Var Var outputVar = m_destCmd.CreateSetOpVar(kv.Key.Type); // Add a mapping for the new output var we've just created SetMappedVar(kv.Key, outputVar); // Add this output var's entries to the new VarMaps leftMap.Add(outputVar, GetMappedVar(kv.Value)); rightMap.Add(outputVar, GetMappedVar((op.VarMap[1])[kv.Key])); } SetOp newSetOp = null; switch (op.OpType) { case OpType.UnionAll: { Var branchDiscriminator = ((UnionAllOp)op).BranchDiscriminator; if (null != branchDiscriminator) { branchDiscriminator = GetMappedVar(branchDiscriminator); } newSetOp = m_destCmd.CreateUnionAllOp(leftMap, rightMap, branchDiscriminator); } break; case OpType.Intersect: { newSetOp = m_destCmd.CreateIntersectOp(leftMap, rightMap); } break; case OpType.Except: { newSetOp = m_destCmd.CreateExceptOp(leftMap, rightMap); } break; default: { Debug.Assert(false, "Unexpected SetOpType"); } break; } return(m_destCmd.CreateNode(newSetOp, children)); }
protected override void VisitSetOp(SetOp op, Node n) { VisitRelOpDefault(op, n); AssertRelOpOrPhysicalOp(n.Child0.Op); AssertRelOpOrPhysicalOp(n.Child1.Op); // // Ensure that the corresponding setOp Vars are all of the same // type // foreach (VarMap varMap in op.VarMap) { foreach (KeyValuePair <Var, Var> kv in varMap) { AssertEqualTypes(kv.Key.Type, kv.Value.Type); } } }
/// <summary> /// SetOp /// /// Converts all SetOps - union/intersect/except. /// Calls VisitChildren() to do the bulk of the work. After that, the VarMaps /// need to be updated to reflect the removal of any structured Vars /// </summary> /// <param name="op"></param> /// <param name="n"></param> /// <returns>new subtree</returns> protected override Node VisitSetOp(SetOp op, Node n) { VisitChildren(n); // Now walk through the first VarMap, and identify the Vars that are needed for (int i = 0; i < op.VarMap.Length; i++) { List<ComputedVar> newComputedVars; op.VarMap[i] = FlattenVarMap(op.VarMap[i], out newComputedVars); if (newComputedVars != null) { n.Children[i] = FixupSetOpChild(n.Children[i], op.VarMap[i], newComputedVars); } } // now get the set of Vars that we will actually need op.Outputs.Clear(); foreach (Var v in op.VarMap[0].Keys) { op.Outputs.Set(v); } return n; }
/// <summary> /// SetOp common processing /// </summary> /// <remarks> /// The input to an IntersectOp or an ExceptOp cannot be a NestOp � that /// would imply that we support distinctness over collections - which /// we don�t. /// /// UnionAllOp is somewhat trickier. We would need a way to percolate keys /// up the UnionAllOp � and I�m ok with not supporting this case for now. /// </remarks> /// <param name="op"></param> /// <param name="n"></param> /// <returns></returns> protected override Node VisitSetOp(SetOp op, Node n) { return NestingNotSupported(op, n); }
protected override void VisitSetOp(SetOp op, Node n) { VisitRelOpDefault(op, n); AssertRelOpOrPhysicalOp(n.Child0.Op); AssertRelOpOrPhysicalOp(n.Child1.Op); // // Ensure that the corresponding setOp Vars are all of the same // type // foreach (var varMap in op.VarMap) { foreach (var kv in varMap) { AssertEqualTypes(kv.Key.Type, kv.Value.Type); } } }
/// <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> /// <param name="op"></param> /// <param name="vars"></param> /// <param name="index"></param> /// <returns></returns> 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; }
protected override void VisitSetOp(SetOp op, Node n) { VisitRelOpDefault(op, n); Map(op.VarMap[0]); Map(op.VarMap[1]); }
/// <summary> /// Common copy path for all SetOps /// </summary> /// <param name="op">The SetOp to Copy (must be one of ExceptOp, IntersectOp, UnionAllOp)</param> /// <param name="n">The Node that references the Op</param> /// <returns>A copy of the original Node that references a copy of the original Op</returns> private Node CopySetOp(SetOp op, Node n) { // Visit the Node's children and map their Vars List<Node> children = ProcessChildren(n); VarMap leftMap = new VarMap(); VarMap rightMap = new VarMap(); foreach (KeyValuePair<Var, Var> kv in op.VarMap[0]) { // Create a new output Var that is a copy of the original output Var Var outputVar = m_destCmd.CreateSetOpVar(kv.Key.Type); // Add a mapping for the new output var we've just created SetMappedVar(kv.Key, outputVar); // Add this output var's entries to the new VarMaps leftMap.Add(outputVar, GetMappedVar(kv.Value)); rightMap.Add(outputVar, GetMappedVar((op.VarMap[1])[kv.Key])); } SetOp newSetOp = null; switch(op.OpType) { case OpType.UnionAll: { Var branchDiscriminator = ((UnionAllOp)op).BranchDiscriminator; if (null != branchDiscriminator) { branchDiscriminator = GetMappedVar(branchDiscriminator); } newSetOp = m_destCmd.CreateUnionAllOp(leftMap, rightMap, branchDiscriminator); } break; case OpType.Intersect: { newSetOp = m_destCmd.CreateIntersectOp(leftMap, rightMap); } break; case OpType.Except: { newSetOp = m_destCmd.CreateExceptOp(leftMap, rightMap); } break; default: { Debug.Assert(false, "Unexpected SetOpType"); } break; } return m_destCmd.CreateNode(newSetOp, children); }
/// <summary> /// SetOp handling /// UnionAllOp handling /// IntersectOp handling /// ExceptOp handling /// /// Visitor for a SetOp. Pushes desired properties to the corresponding /// Vars of the input /// </summary> /// <param name="op">the setop</param> /// <param name="n"></param> protected override void VisitSetOp(SetOp op, Node n) { foreach (VarMap varMap in op.VarMap) foreach (KeyValuePair<Var, Var> kv in varMap) { if (TypeUtils.IsStructuredType(kv.Key.Type)) { // Get the set of expected properties for the unionVar, and // push it down to the inputvars // For Intersect and ExceptOps, we need all properties // from the input // We call GetPropertyRefList() always to initialize // the map, even though we may not use it // PropertyRefList myProps = GetPropertyRefList(kv.Key); if (op.OpType == OpType.Intersect || op.OpType == OpType.Except) { myProps = PropertyRefList.All; // We "want" all properties even on the output of the setop AddPropertyRefs(kv.Key, myProps); } else { myProps = myProps.Clone(); } AddPropertyRefs(kv.Value, myProps); } } VisitChildren(n); }
/// <summary> /// Default handler for all SetOps /// </summary> /// <param name="op">set op</param> /// <param name="n"></param> protected virtual void VisitSetOp(SetOp op, Node n) { VisitRelOpDefault(op, n); }