protected override void VisitJoinOp(JoinBaseOp op, Node n) { VisitRelOpDefault(op, n); if (op.OpType == OpType.CrossJoin) { Assert(n.Children.Count >= 2, "CrossJoinOp needs at least 2 arguments; found only {0}", n.Children.Count); return; } AssertRelOpOrPhysicalOp(n.Child0.Op); AssertRelOpOrPhysicalOp(n.Child1.Op); AssertScalarOp(n.Child2.Op); AssertBooleanOp(n.Child2.Op); }
protected override void VisitJoinOp(JoinBaseOp op, Node n) { using (new Dump.AutoXml(this, (Op)op)) { if (n.Children.Count > 2) { using (new Dump.AutoXml(this, "condition")) this.VisitNode(n.Child2); } using (new Dump.AutoXml(this, "input")) this.VisitNode(n.Child0); using (new Dump.AutoXml(this, "input")) this.VisitNode(n.Child1); } }
protected override NodeInfo VisitJoinOp(JoinBaseOp op, Node n) { if (op.OpType != OpType.InnerJoin && op.OpType != OpType.LeftOuterJoin && op.OpType != OpType.FullOuterJoin) { return(this.Unimplemented(n)); } ExtendedNodeInfo extendedNodeInfo1 = this.InitExtendedNodeInfo(n); ExtendedNodeInfo extendedNodeInfo2 = this.GetExtendedNodeInfo(n.Child0); ExtendedNodeInfo extendedNodeInfo3 = this.GetExtendedNodeInfo(n.Child1); NodeInfo nodeInfo = this.GetNodeInfo(n.Child2); extendedNodeInfo1.Definitions.Or(extendedNodeInfo2.Definitions); extendedNodeInfo1.Definitions.Or(extendedNodeInfo3.Definitions); extendedNodeInfo1.ExternalReferences.Or(extendedNodeInfo2.ExternalReferences); extendedNodeInfo1.ExternalReferences.Or(extendedNodeInfo3.ExternalReferences); extendedNodeInfo1.ExternalReferences.Or(nodeInfo.ExternalReferences); extendedNodeInfo1.ExternalReferences.Minus(extendedNodeInfo1.Definitions); extendedNodeInfo1.Keys.InitFrom(extendedNodeInfo2.Keys, extendedNodeInfo3.Keys); if (op.OpType == OpType.InnerJoin || op.OpType == OpType.LeftOuterJoin) { extendedNodeInfo1.NonNullableDefinitions.InitFrom(extendedNodeInfo2.NonNullableDefinitions); } if (op.OpType == OpType.InnerJoin) { extendedNodeInfo1.NonNullableDefinitions.Or(extendedNodeInfo3.NonNullableDefinitions); } extendedNodeInfo1.NonNullableVisibleDefinitions.InitFrom(extendedNodeInfo2.NonNullableDefinitions); extendedNodeInfo1.NonNullableVisibleDefinitions.Or(extendedNodeInfo3.NonNullableDefinitions); RowCount minRows; RowCount maxRows; if (op.OpType == OpType.FullOuterJoin) { minRows = RowCount.Zero; maxRows = RowCount.Unbounded; } else { maxRows = extendedNodeInfo2.MaxRows > RowCount.One || extendedNodeInfo3.MaxRows > RowCount.One ? RowCount.Unbounded : RowCount.One; minRows = op.OpType != OpType.LeftOuterJoin ? RowCount.Zero : extendedNodeInfo2.MinRows; } extendedNodeInfo1.SetRowCount(minRows, maxRows); return((NodeInfo)extendedNodeInfo1); }
/// <summary> /// Processing for all JoinOps /// </summary> /// <param name="op"> JoinOp </param> /// <param name="n"> Current subtree </param> protected override Node VisitJoinOp(JoinBaseOp op, Node n) { if (base.ProcessJoinOp(n)) { // update the join condition // #479372: Build up a dummy project node over the input, as we always wrap the child of exists n.Child2.Child0 = BuildDummyProjectForExists(n.Child2.Child0); } return n; }
/// <summary> /// Build a join graph for this node for this node if necessary, and process it /// </summary> /// <param name="op"> current join op </param> /// <param name="joinNode"> current join node </param> /// <returns> </returns> protected override Node VisitJoinOp(JoinBaseOp op, Node joinNode) { Node newNode; // Build and process a join graph if necessary if (NeedsJoinGraph(joinNode)) { newNode = ProcessJoinGraph(joinNode); if (newNode != joinNode) { m_treeModified = true; } } else { newNode = joinNode; } // Now do the default processing (ie) visit the children, compute the nodeinfo etc. return VisitDefaultForAllNodes(newNode); }
// <summary> // JoinOp common processing // </summary> protected override Node VisitJoinOp(JoinBaseOp op, Node n) { return ApplyOpJoinOp(op, n); }
/// <summary> /// Computes a NodeInfo for an Inner/LeftOuter/FullOuter JoinOp. /// Definitions = Definitions of my children /// LocalDefinitions = None /// Keys = Concatenation of the keys of my children (if every one of them has keys; otherwise, null) /// External References = any external references from the inputs + any external /// references from the join predicates /// RowCount: /// FullOuterJoin: MinRows = 0, MaxRows = N /// InnerJoin: MinRows = 0; /// MaxRows = N; if both inputs have RowCount lesser than (or equal to) 1, then maxCard = 1 /// OuterJoin: MinRows = leftInput.MinRows /// MaxRows = N; if both inputs have RowCount lesser than (or equal to) 1, then maxCard = 1 /// NonNullableDefinitions: /// FullOuterJoin: None. /// InnerJoin: NonNullableDefinitions of both children /// LeftOuterJoin: NonNullableDefinitions of the left child /// NonNullableInputDefinitions : NonNullabeDefinitions of both children /// </summary> /// <param name="op"> The JoinOp </param> /// <param name="n"> corresponding Node </param> protected override NodeInfo VisitJoinOp(JoinBaseOp op, Node n) { if (!(op.OpType == OpType.InnerJoin || op.OpType == OpType.LeftOuterJoin || op.OpType == OpType.FullOuterJoin)) { return(Unimplemented(n)); } var nodeInfo = InitExtendedNodeInfo(n); // No definitions of my own. Simply inherit from my children // My external references are the union of my children's external // references // And my keys are the concatenation of the keys of each of my // inputs var leftRelOpNodeInfo = GetExtendedNodeInfo(n.Child0); var rightRelOpNodeInfo = GetExtendedNodeInfo(n.Child1); var predNodeInfo = GetNodeInfo(n.Child2); nodeInfo.Definitions.Or(leftRelOpNodeInfo.Definitions); nodeInfo.Definitions.Or(rightRelOpNodeInfo.Definitions); nodeInfo.ExternalReferences.Or(leftRelOpNodeInfo.ExternalReferences); nodeInfo.ExternalReferences.Or(rightRelOpNodeInfo.ExternalReferences); nodeInfo.ExternalReferences.Or(predNodeInfo.ExternalReferences); nodeInfo.ExternalReferences.Minus(nodeInfo.Definitions); nodeInfo.Keys.InitFrom(leftRelOpNodeInfo.Keys, rightRelOpNodeInfo.Keys); //Non-nullable definitions if (op.OpType == OpType.InnerJoin || op.OpType == OpType.LeftOuterJoin) { nodeInfo.NonNullableDefinitions.InitFrom(leftRelOpNodeInfo.NonNullableDefinitions); } if (op.OpType == OpType.InnerJoin) { nodeInfo.NonNullableDefinitions.Or(rightRelOpNodeInfo.NonNullableDefinitions); } nodeInfo.NonNullableVisibleDefinitions.InitFrom(leftRelOpNodeInfo.NonNullableDefinitions); nodeInfo.NonNullableVisibleDefinitions.Or(rightRelOpNodeInfo.NonNullableDefinitions); RowCount maxRows; RowCount minRows; if (op.OpType == OpType.FullOuterJoin) { minRows = RowCount.Zero; maxRows = RowCount.Unbounded; } else { if ((leftRelOpNodeInfo.MaxRows > RowCount.One) || (rightRelOpNodeInfo.MaxRows > RowCount.One)) { maxRows = RowCount.Unbounded; } else { maxRows = RowCount.One; } if (op.OpType == OpType.LeftOuterJoin) { minRows = leftRelOpNodeInfo.MinRows; } else { minRows = RowCount.Zero; } } nodeInfo.SetRowCount(minRows, maxRows); return(nodeInfo); }
/// <summary> /// Processing for all JoinOps /// </summary> /// <param name="op">JoinOp</param> /// <param name="n">Current subtree</param> /// <returns></returns> protected override Node VisitJoinOp(JoinBaseOp op, Node n) { // Only LeftOuterJoin and InnerJoin are handled by JoinElimination if (op.OpType == OpType.InnerJoin || op.OpType == OpType.LeftOuterJoin) { m_compilerState.MarkPhaseAsNeeded(PlanCompilerPhase.JoinElimination); } // If a subquery was added with an exists node, we have to go througth Normalization if (base.ProcessJoinOp(n)) { m_compilerState.MarkPhaseAsNeeded(PlanCompilerPhase.Normalization); } return n; }
/// <summary> /// Default handler for all JoinOps /// </summary> /// <param name="op"> join op </param> /// <param name="n"> </param> protected virtual void VisitJoinOp(JoinBaseOp op, Node n) { VisitRelOpDefault(op, n); }
///<summary> /// JoinOp handling /// CrossJoinOp handling /// InnerJoinOp handling /// LeftOuterJoinOp handling /// FullOuterJoinOp handling /// /// Handler for all JoinOps. For all joins except cross joins, process /// the predicate first, and then the inputs - the inputs can be processed /// in any order. /// /// For cross joins, simply process all the (relop) inputs ///</summary> ///<param name="op"> join op </param> ///<param name="n"> </param> protected override void VisitJoinOp(JoinBaseOp op, Node n) { if (n.Op.OpType == OpType.CrossJoin) { VisitChildren(n); } else { VisitNode(n.Child2); // the predicate first VisitNode(n.Child0); // then, the left input VisitNode(n.Child1); // the right input } }
protected virtual void VisitJoinOp(JoinBaseOp op, Node n) { this.VisitRelOpDefault((RelOp)op, n); }
protected virtual void VisitJoinOp(JoinBaseOp op, Node n) { VisitRelOpDefault(op, n); }
// <summary> // A default processor for all JoinOps. // Allows new visitors to just override this to handle all JoinOps. // </summary> // <param name="op"> the JoinOp </param> // <param name="n"> the node to process </param> // <returns> a potentially modified subtree </returns> protected virtual TResultType VisitJoinOp(JoinBaseOp op, Node n) { return(VisitRelOpDefault(op, n)); }