public override void Visit(WBooleanBinaryExpression node)
 {
     if (node.BooleanExpressionType == BooleanBinaryExpressionType.And)
     {
         if (_checkNodeEdgeReferenceVisitor.Invoke(node.FirstExpr))
         {
             UpdateWherClause(_nodeEdgePredicatesWhenClause, node.FirstExpr);
         }
         else
         {
             base.Visit(node.FirstExpr);
         }
         if (_checkNodeEdgeReferenceVisitor.Invoke(node.SecondExpr))
         {
             UpdateWherClause(_nodeEdgePredicatesWhenClause, node.SecondExpr);
         }
         else
         {
             base.Visit(node.SecondExpr);
         }
     }
     else
     {
         if (_checkNodeEdgeReferenceVisitor.Invoke(node))
         {
             UpdateWherClause(_nodeEdgePredicatesWhenClause, node);
         }
     }
 }
Пример #2
0
 /// <summary>
 /// Converts edge attribute predicates into a boolean expression, which is used for
 /// constructing queries for retrieving edge statistics
 /// </summary>
 /// <returns></returns>
 public override WBooleanExpression RetrievePredicatesExpression()
 {
     if (AttributeValueDict != null)
     {
         WBooleanExpression res = null;
         foreach (var tuple in AttributeValueDict)
         {
             res = WBooleanBinaryExpression.Conjunction(res, new WBooleanComparisonExpression
             {
                 ComparisonType = BooleanComparisonType.Equals,
                 FirstExpr      =
                     new WColumnReferenceExpression
                 {
                     MultiPartIdentifier =
                         new WMultiPartIdentifier(new Identifier {
                         Value = LinkAlias
                     },
                                                  new Identifier {
                         Value = tuple.Key
                     })
                 },
                 SecondExpr = new WValueExpression {
                     Value = tuple.Value
                 }
             });
         }
         return(res);
     }
     return(null);
 }
 public override void Visit(WBooleanBinaryExpression node)
 {
     if (node.BooleanExpressionType == BooleanBinaryExpressionType.And)
     {
         base.Visit(node);
     }
     else
     {
         Attach(new WBooleanParenthesisExpression{ Expression = node });
     }
 }
 public override void Visit(WBooleanBinaryExpression node)
 {
     if (node.BooleanExpressionType == BooleanBinaryExpressionType.And)
     {
         base.Visit(node);
     }
     else
     {
         Attach(node);
     }
 }
Пример #5
0
        // WBooleanExpression
        public override void Visit(WBooleanBinaryExpression node)
        {
            node.FirstExpr.Accept(this);
            string left = this.dfsStack.Pop();

            node.SecondExpr.Accept(this);
            string right = this.dfsStack.Pop();

            string nodeStr = $"{left} {TsqlFragmentToString.BooleanExpressionType(node.BooleanExpressionType)} {right}";

            this.dfsStack.Push(nodeStr);
        }
Пример #6
0
 /// <summary>
 /// Converts edge attribute predicates into a boolean expression, which is used for
 /// constructing queries for retrieving edge statistics
 /// </summary>
 /// <returns></returns>
 public virtual WBooleanExpression RetrievePredicatesExpression()
 {
     if (Predicates != null)
     {
         WBooleanExpression res = null;
         foreach (var expression in Predicates)
         {
             res = WBooleanBinaryExpression.Conjunction(res, expression);
         }
         return(res);
     }
     return(null);
 }
Пример #7
0
 public override void Visit(WBooleanBinaryExpression node)
 {
     if (node.BooleanExpressionType == BooleanBinaryExpressionType.And)
     {
         base.Visit(node);
     }
     else
     {
         Attach(new WBooleanParenthesisExpression {
             Expression = node
         });
     }
 }
 public override void Visit(WBooleanBinaryExpression node)
 {
     if (node.BooleanExpressionType == BooleanBinaryExpressionType.And)
     {
         if (_checkNodeEdgeReferenceVisitor.Invoke(node.FirstExpr))
         {
             UpdateWherClause(_nodeEdgePredicatesWhenClause, node.FirstExpr);
         }
         else
         {
             base.Visit(node.FirstExpr);
         }
         if (_checkNodeEdgeReferenceVisitor.Invoke(node.SecondExpr))
         {
             UpdateWherClause(_nodeEdgePredicatesWhenClause, node.SecondExpr);
         }
         else
         {
             base.Visit(node.SecondExpr);
         }
     }
     else
     {
         if (_checkNodeEdgeReferenceVisitor.Invoke(node))
         {
             UpdateWherClause(_nodeEdgePredicatesWhenClause,node);
         }
     }
 }
 public override void Visit(WBooleanBinaryExpression node)
 {
     if (node.BooleanExpressionType == BooleanBinaryExpressionType.And)
     {
         base.Visit(node);
     }
     else
     {
         Attach(node);
     }
 }
Пример #10
0
        private WBooleanExpression ParseBooleanExpression(BooleanExpression bexpr)
        {
            if (bexpr == null)
            {
                return null;
            }

            switch (bexpr.GetType().Name)
            {
                case "BooleanBinaryExpression":
                    {
                        var oexpr = bexpr as BooleanBinaryExpression;
                        var pexpr = new WBooleanBinaryExpression
                        {
                            FirstExpr = ParseBooleanExpression(oexpr.FirstExpression),
                            SecondExpr = ParseBooleanExpression(oexpr.SecondExpression),
                            BooleanExpressionType = oexpr.BinaryExpressionType,
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        return pexpr;
                    }
                case "BooleanComparisonExpression":
                    {
                        var oexpr = bexpr as BooleanComparisonExpression;
                        var pexpr = new WBooleanComparisonExpression
                        {
                            ComparisonType = oexpr.ComparisonType,
                            FirstExpr = ParseScalarExpression(oexpr.FirstExpression),
                            SecondExpr = ParseScalarExpression(oexpr.SecondExpression),
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        return pexpr;
                    }
                case "BooleanIsNullExpression":
                    {
                        var oexpr = bexpr as BooleanIsNullExpression;
                        var pexpr = new WBooleanIsNullExpression
                        {
                            IsNot = oexpr.IsNot,
                            Expression = ParseScalarExpression(oexpr.Expression),
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        return pexpr;
                    }
                case "BooleanNotExpression":
                    {
                        var oexpr = bexpr as BooleanNotExpression;
                        var pexpr = new WBooleanNotExpression
                        {
                            Expression = ParseBooleanExpression(oexpr.Expression),
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        return pexpr;
                    }
                case "BooleanParenthesisExpression":
                    {
                        var oexpr = bexpr as BooleanParenthesisExpression;
                        var pexpr = new WBooleanParenthesisExpression
                        {
                            Expression = ParseBooleanExpression(oexpr.Expression),
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        return pexpr;
                    }
                case "BooleanTernaryExpression":
                    {
                        var oexpr = bexpr as BooleanTernaryExpression;
                        var pexpr = new WBetweenExpression
                        {
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        switch (oexpr.TernaryExpressionType)
                        {
                            case BooleanTernaryExpressionType.Between:
                                pexpr.NotDefined = false;
                                break;
                            case BooleanTernaryExpressionType.NotBetween:
                                pexpr.NotDefined = true;
                                break;
                            default:
                                throw new GraphViewException("Undefined tenary expression type");
                        }

                        pexpr.FirstExpr = ParseScalarExpression(oexpr.FirstExpression);
                        pexpr.SecondExpr = ParseScalarExpression(oexpr.SecondExpression);
                        pexpr.ThirdExpr = ParseScalarExpression(oexpr.ThirdExpression);

                        return pexpr;
                    }
                case "ExistsPredicate":
                    {
                        var oexpr = bexpr as ExistsPredicate;
                        var pexpr = new WExistsPredicate
                        {
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                            Subquery =
                                new WScalarSubquery
                                {
                                    SubQueryExpr = ParseSelectQueryStatement(oexpr.Subquery.QueryExpression),
                                    FirstTokenIndex = oexpr.Subquery.FirstTokenIndex,
                                    LastTokenIndex = oexpr.Subquery.LastTokenIndex,
                                }
                        };

                        return pexpr;
                    }
                case "InPredicate":
                    {
                        var oexpr = bexpr as InPredicate;
                        var pexpr = new WInPredicate
                        {
                            Expression = ParseScalarExpression(oexpr.Expression),
                            NotDefined = oexpr.NotDefined,
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        if (oexpr.Subquery != null)
                        {
                            pexpr.Subquery = new WScalarSubquery
                            {
                                SubQueryExpr = ParseSelectQueryStatement(oexpr.Subquery.QueryExpression),
                                FirstTokenIndex = oexpr.Subquery.FirstTokenIndex,
                                LastTokenIndex = oexpr.Subquery.LastTokenIndex,

                            };
                        }
                        else
                        {
                            pexpr.Values = new List<WScalarExpression>(oexpr.Values.Count);
                            foreach (var wexp in oexpr.Values.Select(ParseScalarExpression).Where(wexp => wexp != null))
                            {
                                pexpr.Values.Add(wexp);
                            }
                        }

                        return pexpr;
                    }
                case "LikePredicate":
                    {
                        var oexpr = bexpr as LikePredicate;
                        var pexpr = new WLikePredicate
                        {
                            EscapeExpr = ParseScalarExpression(oexpr.EscapeExpression),
                            FirstExpr = ParseScalarExpression(oexpr.FirstExpression),
                            SecondExpr = ParseScalarExpression(oexpr.SecondExpression),
                            NotDefined = oexpr.NotDefined,
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                        };

                        return pexpr;
                    }
                case "SubqueryComparisonPredicate":
                    {
                        var oexpr = bexpr as SubqueryComparisonPredicate;
                        var pexpr = new WSubqueryComparisonPredicate
                        {
                            FirstTokenIndex = oexpr.FirstTokenIndex,
                            LastTokenIndex = oexpr.LastTokenIndex,
                            Subquery = new WScalarSubquery()
                            {
                                SubQueryExpr = ParseSelectQueryStatement(oexpr.Subquery.QueryExpression),
                                FirstTokenIndex = oexpr.Subquery.FirstTokenIndex,
                                LastTokenIndex = oexpr.Subquery.LastTokenIndex

                            },
                            ComparisonType = oexpr.ComparisonType,
                            Expression = ParseScalarExpression(oexpr.Expression),
                            SubqueryComparisonType = oexpr.SubqueryComparisonPredicateType,
                        };

                        return pexpr;
                    }
                default:
                    {
                        return null;
                    }
            }
        }
Пример #11
0
 public virtual void Visit(WBooleanBinaryExpression node)
 {
     node.AcceptChildren(this);
 }
Пример #12
0
 public virtual void Visit(WBooleanBinaryExpression node)
 {
     node.AcceptChildren(this);
 }
Пример #13
0
        /// <summary>
        /// Transit from current component to the new component in the next state given the Node Unit
        /// </summary>
        /// <param name="candidateTree"></param>
        /// <param name="densityDict"></param>
        /// <param name="subGraph"></param>
        /// <param name="statisticsCalculator"></param>
        /// <returns></returns>
        public MatchComponent GetNextState(
            OneHeightTree candidateTree,
            Dictionary <string, double> densityDict,
            IMatchJoinStatisticsCalculator statisticsCalculator)
        {
            var newComponent = new MatchComponent(this);
            var root         = candidateTree.TreeRoot;

            WBooleanExpression joinCondition = null;
            string             nodeName      = "";


            // Update Nodes
            if (newComponent.MaterializedNodeSplitCount.ContainsKey(root))
            {
                newComponent.MaterializedNodeSplitCount[root]++;
                nodeName      = newComponent.GetNodeRefName(root);
                joinCondition = new WBooleanComparisonExpression
                {
                    FirstExpr = new WColumnReferenceExpression
                    {
                        ColumnType          = ColumnType.Regular,
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {
                            Value = root.RefAlias
                        },
                            new Identifier {
                            Value = "GlobalNodeId"
                        }
                            ),
                    },
                    SecondExpr = new WColumnReferenceExpression
                    {
                        ColumnType          = ColumnType.Regular,
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {
                            Value = nodeName
                        },
                            new Identifier {
                            Value = "GlobalNodeId"
                        }
                            ),
                    },
                    ComparisonType = BooleanComparisonType.Equals
                };
            }
            else
            {
                nodeName = root.RefAlias;
                newComponent.Nodes.Add(root);
                newComponent.MaterializedNodeSplitCount[root] = 0;
                newComponent.StatisticsDict[root]             = new ColumnStatistics {
                    Selectivity = 1.0 / root.TableRowCount
                };
            }

            // Constructs table reference
            WTableReference nodeTable = new WNamedTableReference
            {
                Alias = new Identifier {
                    Value = nodeName
                },
                TableObjectName = root.TableObjectName
            };
            WTableReference compTable = newComponent.TableRef;

            // Updates join conditions
            double selectivity  = 1.0;
            double degrees      = 1.0;
            var    DensityCount = new Dictionary <string, int>(StringComparer.CurrentCultureIgnoreCase);

            List <MatchEdge> inEdges;

            if (newComponent.UnmaterializedNodeMapping.TryGetValue(root, out inEdges))
            {
                var  firstEdge    = inEdges.First();
                bool materialized = newComponent.EdgeMaterilizedDict[firstEdge];
                newComponent.UnmaterializedNodeMapping.Remove(root);
                selectivity *= 1.0 / root.TableRowCount;

                // Component materialized edge to root
                if (materialized)
                {
                    joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition, new WBooleanComparisonExpression
                    {
                        FirstExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = firstEdge.EdgeAlias
                            },
                                new Identifier {
                                Value = "Sink"
                            }
                                ),
                        },
                        SecondExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = nodeName
                            },
                                new Identifier {
                                Value = "GlobalNodeId"
                            }
                                )
                        },
                        ComparisonType = BooleanComparisonType.Equals
                    });

                    //var statistics = ColumnStatistics.UpdateHistogram(newComponent.StatisticsDict[root],
                    //    new ColumnStatistics {Selectivity = 1.0/root.TableRowCount});
                    //selectivity *= statistics.Selectivity;
                    //newComponent.StatisticsDict[root] = statistics;

                    if (DensityCount.ContainsKey(root.TableObjectName.ToString()))
                    {
                        DensityCount[root.TableObjectName.ToString()]++;
                    }
                    else
                    {
                        DensityCount[root.TableObjectName.ToString()] = 1;
                    }
                }
                // Component unmaterialized edge to root
                else
                {
                    ColumnStatistics statistics = null;
                    foreach (var edge in inEdges)
                    {
                        // Update component table
                        compTable = SpanTableRef(compTable, edge, newComponent.GetNodeRefName(edge.SourceNode));

                        newComponent.EdgeMaterilizedDict[edge] = true;
                        joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                             new WBooleanComparisonExpression
                        {
                            FirstExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = edge.EdgeAlias
                                },
                                    new Identifier {
                                    Value = "Sink"
                                }
                                    ),
                            },
                            SecondExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = nodeName
                                },
                                    new Identifier {
                                    Value = "GlobalNodeId"
                                }
                                    )
                            },
                            ComparisonType = BooleanComparisonType.Equals
                        });
                        statistics = ColumnStatistics.UpdateHistogram(statistics,
                                                                      newComponent.Context.GetEdgeStatistics(edge));
                        selectivity *= statistics.Selectivity;
                    }
                    newComponent.StatisticsDict[root] = statistics;

                    if (DensityCount.ContainsKey(root.TableObjectName.ToString()))
                    {
                        DensityCount[root.TableObjectName.ToString()] += inEdges.Count;
                    }
                    else
                    {
                        DensityCount[root.TableObjectName.ToString()] = inEdges.Count;
                    }
                }
            }

            var jointEdges      = candidateTree.MaterializedEdges;
            int sinkToSinkCount = 0;

            foreach (var jointEdge in jointEdges)
            {
                // Update node table
                nodeTable = SpanTableRef(nodeTable, jointEdge, nodeName);
                degrees  *= jointEdge.AverageDegree;

                newComponent.EdgeMaterilizedDict[jointEdge] = true;
                var sinkNode = jointEdge.SinkNode;
                // Leaf to component materialized node
                if (newComponent.MaterializedNodeSplitCount.ContainsKey(sinkNode))
                {
                    joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                         new WBooleanComparisonExpression
                    {
                        FirstExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = jointEdge.EdgeAlias
                            },
                                new Identifier {
                                Value = "Sink"
                            }
                                ),
                        },
                        SecondExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = sinkNode.RefAlias
                            },
                                new Identifier {
                                Value = "GlobalNodeId"
                            }
                                )
                        },
                        ComparisonType = BooleanComparisonType.Equals
                    });
                    var statistics = ColumnStatistics.UpdateHistogram(newComponent.StatisticsDict[sinkNode],
                                                                      newComponent.Context.GetEdgeStatistics(jointEdge));
                    selectivity *= statistics.Selectivity;
                    newComponent.StatisticsDict[sinkNode] = statistics;

                    if (DensityCount.ContainsKey(sinkNode.TableObjectName.ToString()))
                    {
                        DensityCount[sinkNode.TableObjectName.ToString()]++;
                    }
                    else
                    {
                        DensityCount[sinkNode.TableObjectName.ToString()] = 1;
                    }
                }
                // Leaf to component unmaterialized node
                else
                {
                    inEdges = newComponent.UnmaterializedNodeMapping[sinkNode];
                    var  firstEdge      = inEdges.First();
                    bool materlizedEdge = newComponent.EdgeMaterilizedDict[firstEdge];

                    // Leaf to materialized leaf
                    if (materlizedEdge)
                    {
                        joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                             new WBooleanComparisonExpression
                        {
                            FirstExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = jointEdge.EdgeAlias
                                },
                                    new Identifier {
                                    Value = "Sink"
                                }
                                    ),
                            },
                            SecondExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = firstEdge.EdgeAlias
                                },
                                    new Identifier {
                                    Value = "Sink"
                                }
                                    )
                            },
                            ComparisonType = BooleanComparisonType.Equals
                        });

                        sinkToSinkCount++;
                        var statistics = ColumnStatistics.UpdateHistogram(newComponent.StatisticsDict[sinkNode],
                                                                          newComponent.Context.GetEdgeStatistics(jointEdge));
                        selectivity *= statistics.Selectivity;
                        newComponent.StatisticsDict[sinkNode] = statistics;
                    }
                    // Leaf to unmaterialized leaf
                    else
                    {
                        ColumnStatistics compSinkNodeStatistics = null;
                        foreach (var inEdge in inEdges)
                        {
                            compTable = SpanTableRef(compTable, inEdge, newComponent.GetNodeRefName(inEdge.SourceNode));
                            newComponent.EdgeMaterilizedDict[inEdge] = true;
                            joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                                 new WBooleanComparisonExpression
                            {
                                FirstExpr = new WColumnReferenceExpression
                                {
                                    ColumnType          = ColumnType.Regular,
                                    MultiPartIdentifier = new WMultiPartIdentifier(
                                        new Identifier {
                                        Value = jointEdge.EdgeAlias
                                    },
                                        new Identifier {
                                        Value = "Sink"
                                    }
                                        ),
                                },
                                SecondExpr = new WColumnReferenceExpression
                                {
                                    ColumnType          = ColumnType.Regular,
                                    MultiPartIdentifier = new WMultiPartIdentifier(
                                        new Identifier {
                                        Value = inEdge.EdgeAlias
                                    },
                                        new Identifier {
                                        Value = "Sink"
                                    }
                                        )
                                },
                                ComparisonType = BooleanComparisonType.Equals
                            });

                            sinkToSinkCount++;
                            var leafToLeafStatistics = statisticsCalculator.GetLeafToLeafStatistics(jointEdge, inEdge);
                            selectivity           *= leafToLeafStatistics.Selectivity;
                            compSinkNodeStatistics =
                                ColumnStatistics.UpdateHistogram(compSinkNodeStatistics,
                                                                 newComponent.Context.GetEdgeStatistics(inEdge));
                        }
                        newComponent.StatisticsDict[sinkNode] = compSinkNodeStatistics;
                    }
                }
            }

            var unmatEdges = candidateTree.UnmaterializedEdges;

            foreach (var unmatEdge in unmatEdges)
            {
                newComponent.EdgeMaterilizedDict[unmatEdge] = false;
                newComponent.Nodes.Add(unmatEdge.SinkNode);
                var sinkNodeInEdges = newComponent.UnmaterializedNodeMapping.GetOrCreate(unmatEdge.SinkNode);
                sinkNodeInEdges.Add(unmatEdge);
                degrees *= unmatEdge.AverageDegree;
            }

            // Calculate Estimated Join Selectivity & Estimated Node Size
            double estimatedSelectity = 1.0;
            int    count    = 0;
            bool   sinkJoin = false;

            foreach (var item in densityDict.Where(e => DensityCount.ContainsKey(e.Key)))
            {
                var density            = item.Value;
                var curJoinCount       = DensityCount[item.Key];
                var curJoinSelectitivy = Math.Pow(density, 2 - Math.Pow(2, 1 - curJoinCount));
                if (!sinkJoin && ColumnStatistics.DefaultDensity < density)
                {
                    var curSinkJoinSelectivity = Math.Pow(ColumnStatistics.DefaultDensity,
                                                          2 - Math.Pow(2, 1 - sinkToSinkCount));
                    estimatedSelectity *= Math.Pow(curSinkJoinSelectivity, Math.Pow(2, -count));
                    count   += sinkToSinkCount;
                    sinkJoin = true;
                }
                estimatedSelectity *= Math.Pow(curJoinSelectitivy, Math.Pow(2, -count));
                count += curJoinCount;
            }

            var estimatedNodeUnitSize = root.EstimatedRows *
                                        Math.Pow(1000, candidateTree.MaterializedEdges.Count + candidateTree.UnmaterializedEdges.Count);


            // Update Table Reference
            newComponent.TableRef = GetPlanAndUpdateCost(candidateTree, newComponent, nodeTable, compTable, joinCondition,
                                                         degrees, selectivity, estimatedNodeUnitSize, estimatedSelectity);

            return(newComponent);
        }
Пример #14
0
        private WBooleanExpression ConstructJoinCondition(
            CandidateJoinUnit candidateTree,
            IMatchJoinStatisticsCalculator statisticsCalculator,
            GraphMetaData metaData,
            out double joinSelectivity,
            out double sqlEstimatedJoinSelectivity)
        {
            joinSelectivity             = 1.0;
            sqlEstimatedJoinSelectivity = 1.0;


            var root = candidateTree.TreeRoot;

            WBooleanExpression joinCondition = null;
            string             nodeName      = "";


            // Update Nodes
            if (MaterializedNodeSplitCount.ContainsKey(root))
            {
                MaterializedNodeSplitCount[root]++;
                nodeName      = GetNodeRefName(root);
                joinCondition = new WBooleanComparisonExpression
                {
                    FirstExpr = new WColumnReferenceExpression
                    {
                        ColumnType          = ColumnType.Regular,
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {
                            Value = root.RefAlias
                        },
                            new Identifier {
                            Value = "GlobalNodeId"
                        }
                            ),
                    },
                    SecondExpr = new WColumnReferenceExpression
                    {
                        ColumnType          = ColumnType.Regular,
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {
                            Value = nodeName
                        },
                            new Identifier {
                            Value = "GlobalNodeId"
                        }
                            ),
                    },
                    ComparisonType = BooleanComparisonType.Equals
                };
            }
            else
            {
                nodeName = root.RefAlias;
                if (!Nodes.Contains(root))
                {
                    Nodes.Add(root);
                }
                MaterializedNodeSplitCount[root] = 0;
            }

            List <double> densityList = new List <double>();

            List <MatchEdge> inEdges;

            if (UnmaterializedNodeMapping.TryGetValue(root, out inEdges))
            {
                var  firstEdge    = inEdges.First();
                bool materialized = EdgeMaterilizedDict[firstEdge];
                UnmaterializedNodeMapping.Remove(root);
                joinSelectivity *= 1.0 / root.TableRowCount;

                // Component materialized edge to root
                if (materialized)
                {
                    joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition, new WBooleanComparisonExpression
                    {
                        FirstExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = firstEdge.EdgeAlias
                            },
                                new Identifier {
                                Value = "Sink"
                            }
                                ),
                        },
                        SecondExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = nodeName
                            },
                                new Identifier {
                                Value = "GlobalNodeId"
                            }
                                )
                        },
                        ComparisonType = BooleanComparisonType.Equals
                    });

                    densityList.Add(root.GlobalNodeIdDensity);
                }
                // Component unmaterialized edge to root
                else
                {
                    Statistics statistics = null;
                    foreach (var edge in inEdges)
                    {
                        // Update component table
                        TableRef = SpanTableRef(TableRef, edge, GetNodeRefName(edge.SourceNode), metaData);

                        EdgeMaterilizedDict[edge] = true;
                        joinCondition             = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                                         new WBooleanComparisonExpression
                        {
                            FirstExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = edge.EdgeAlias
                                },
                                    new Identifier {
                                    Value = "Sink"
                                }
                                    ),
                            },
                            SecondExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = nodeName
                                },
                                    new Identifier {
                                    Value = "GlobalNodeId"
                                }
                                    )
                            },
                            ComparisonType = BooleanComparisonType.Equals
                        });
                        double selectivity;
                        statistics = Statistics.UpdateHistogram(statistics,
                                                                edge.Statistics, out selectivity);
                        joinSelectivity *= selectivity;
                        densityList.Add(root.GlobalNodeIdDensity);
                    }
                    SinkNodeStatisticsDict[root] = statistics;
                }
            }

            var jointEdges = candidateTree.MaterializedEdges;

            foreach (var jointEdge in jointEdges)
            {
                EdgeMaterilizedDict[jointEdge] = true;
                var sinkNode = jointEdge.SinkNode;
                // Leaf to component materialized node
                if (MaterializedNodeSplitCount.ContainsKey(sinkNode))
                {
                    joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                         new WBooleanComparisonExpression
                    {
                        FirstExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = jointEdge.EdgeAlias
                            },
                                new Identifier {
                                Value = "Sink"
                            }
                                ),
                        },
                        SecondExpr = new WColumnReferenceExpression
                        {
                            ColumnType          = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {
                                Value = sinkNode.RefAlias
                            },
                                new Identifier {
                                Value = "GlobalNodeId"
                            }
                                )
                        },
                        ComparisonType = BooleanComparisonType.Equals
                    });
                    Statistics sinkNodeStatistics;
                    if (!SinkNodeStatisticsDict.TryGetValue(sinkNode, out sinkNodeStatistics))
                    {
                        sinkNodeStatistics = null;
                        joinSelectivity   *= 1.0 / sinkNode.TableRowCount;
                    }
                    double selectivity;
                    var    statistics = Statistics.UpdateHistogram(sinkNodeStatistics,
                                                                   jointEdge.Statistics, out selectivity);
                    joinSelectivity *= selectivity;
                    SinkNodeStatisticsDict[sinkNode] = statistics;
                    densityList.Add(sinkNode.GlobalNodeIdDensity);
                }
                // Leaf to component unmaterialized node
                else
                {
                    inEdges = UnmaterializedNodeMapping[sinkNode];
                    var  firstEdge      = inEdges.First();
                    bool materlizedEdge = EdgeMaterilizedDict[firstEdge];

                    // Leaf to materialized leaf
                    if (materlizedEdge)
                    {
                        joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                             new WBooleanComparisonExpression
                        {
                            FirstExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = jointEdge.EdgeAlias
                                },
                                    new Identifier {
                                    Value = "Sink"
                                }
                                    ),
                            },
                            SecondExpr = new WColumnReferenceExpression
                            {
                                ColumnType          = ColumnType.Regular,
                                MultiPartIdentifier = new WMultiPartIdentifier(
                                    new Identifier {
                                    Value = firstEdge.EdgeAlias
                                },
                                    new Identifier {
                                    Value = "Sink"
                                }
                                    )
                            },
                            ComparisonType = BooleanComparisonType.Equals
                        });

                        densityList.Add(Statistics.DefaultDensity);
                        double selectivity;
                        var    statistics = Statistics.UpdateHistogram(SinkNodeStatisticsDict[sinkNode],
                                                                       jointEdge.Statistics, out selectivity);
                        joinSelectivity *= selectivity;
                        SinkNodeStatisticsDict[sinkNode] = statistics;
                    }
                    // Leaf to unmaterialized leaf
                    else
                    {
                        Statistics compSinkNodeStatistics = null;
                        foreach (var inEdge in inEdges)
                        {
                            TableRef = SpanTableRef(TableRef, inEdge, GetNodeRefName(inEdge.SourceNode), metaData);
                            EdgeMaterilizedDict[inEdge] = true;
                            joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition,
                                                                                 new WBooleanComparisonExpression
                            {
                                FirstExpr = new WColumnReferenceExpression
                                {
                                    ColumnType          = ColumnType.Regular,
                                    MultiPartIdentifier = new WMultiPartIdentifier(
                                        new Identifier {
                                        Value = jointEdge.EdgeAlias
                                    },
                                        new Identifier {
                                        Value = "Sink"
                                    }
                                        ),
                                },
                                SecondExpr = new WColumnReferenceExpression
                                {
                                    ColumnType          = ColumnType.Regular,
                                    MultiPartIdentifier = new WMultiPartIdentifier(
                                        new Identifier {
                                        Value = inEdge.EdgeAlias
                                    },
                                        new Identifier {
                                        Value = "Sink"
                                    }
                                        )
                                },
                                ComparisonType = BooleanComparisonType.Equals
                            });

                            densityList.Add(Statistics.DefaultDensity);

                            double selectivity;
                            var    leafToLeafStatistics = statisticsCalculator.GetLeafToLeafStatistics(jointEdge, inEdge,
                                                                                                       out selectivity);
                            joinSelectivity       *= selectivity;
                            compSinkNodeStatistics =
                                Statistics.UpdateHistogram(compSinkNodeStatistics,
                                                           inEdge.Statistics, out selectivity);
                        }
                        SinkNodeStatisticsDict[sinkNode] = compSinkNodeStatistics;
                    }
                }
            }

            var unmatEdges = candidateTree.UnmaterializedEdges;

            foreach (var unmatEdge in unmatEdges)
            {
                EdgeMaterilizedDict[unmatEdge] = false;
                if (!Nodes.Contains(unmatEdge.SinkNode))
                {
                    Nodes.Add(unmatEdge.SinkNode);
                }
                var sinkNodeInEdges = UnmaterializedNodeMapping.GetOrCreate(unmatEdge.SinkNode);
                sinkNodeInEdges.Add(unmatEdge);
            }

            // Calculate Estimated Join Selectivity & Estimated Node Size
            densityList.Sort();
            for (int i = densityList.Count - 1; i >= 0; i--)
            {
                sqlEstimatedJoinSelectivity *= Math.Sqrt(sqlEstimatedJoinSelectivity) * densityList[i];
            }

            return(joinCondition);
        }
Пример #15
0
        /// <summary>
        /// Calculate join costs and update components using optimal join method & order
        /// </summary>
        /// <param name="nodeUnitCandidate"></param>
        /// <param name="joinCondition"></param>
        /// <param name="joinSelectivity"></param>
        /// <param name="estimatedSelectivity"></param>
        /// <returns></returns>
        private void ConstructPhysicalJoinAndUpdateCost(
            CandidateJoinUnit nodeUnitCandidate,
            WBooleanExpression joinCondition,
            double joinSelectivity,
            double estimatedSelectivity,
            GraphMetaData metaData)
        {
            var nodeDegrees           = nodeUnitCandidate.EdgeDegrees;
            var nodeUnitSize          = nodeUnitCandidate.TreeRoot.EstimatedRows * nodeDegrees;
            var estimatedNodeUnitSize = nodeUnitCandidate.TreeRoot.EstimatedRows *
                                        nodeUnitCandidate.SqlEstimatedEdgeDegrees;
            var componentSize     = Cardinality;
            var estimatedCompSize = SqlEstimatedSize;

            var node = nodeUnitCandidate.TreeRoot;

            // If the node is already in the component, then only multiply the degree to get the size
            double nodeUnitActualSize;
            double newCompEstSize;

            if (MaterializedNodeSplitCount[node] > 0)
            {
                nodeUnitActualSize = nodeDegrees;
                var cEstEdge = Math.Pow(1000, EdgeMaterilizedDict.Count(e => !e.Value));
                var cSize    = SqlEstimatedSize / cEstEdge;
                var nSize    = node.EstimatedRows;
                if (nSize > cSize)
                {
                    newCompEstSize = estimatedNodeUnitSize * cEstEdge * estimatedSelectivity;
                }
                else
                {
                    newCompEstSize = SqlEstimatedSize * Math.Pow(1000, nodeUnitCandidate.UnmaterializedEdges.Count) * estimatedSelectivity;
                }
            }
            else
            {
                nodeUnitActualSize = nodeUnitSize;
                newCompEstSize     = SqlEstimatedSize * estimatedNodeUnitSize * estimatedSelectivity;
            }
            newCompEstSize = newCompEstSize < 1.0 ? 1.0 : newCompEstSize;



            bool firstJoin = MaterializedNodeSplitCount.Count == 2 &&
                             MaterializedNodeSplitCount.All(e => e.Value == 0);

            // Update TableRef
            double loopJoinOuterThreshold = 1e4; //1e6;
            double sizeFactor             = 5;   //1000;
            double maxMemory = 1e8;
            double loopCost  = componentSize * Math.Log(nodeUnitCandidate.TreeRoot.EstimatedRows, 512) * 0.20;
            double hashCost  = componentSize + nodeUnitSize;
            double cost;

            // Loop Join
            if (
                nodeUnitCandidate.MaterializedEdges.Count == 0 && // the joins are purely leaf to sink join
                (
                    //componentSize < loopJoinOuterThreshold ||     // the outer table is relatively small
                    loopCost < hashCost ||
                    (DeltaMemory + componentSize > maxMemory && DeltaMemory + nodeUnitSize > maxMemory) // memory is in pressure
                )
                )
            {
                if (firstJoin)
                {
                    RightestTableRefSize = nodeUnitCandidate.TreeRoot.EstimatedRows;
                    RightestTableAlias   = GetNodeRefName(node);
                }
                TotalMemory             = DeltaMemory;
                SqlEstimatedTotalMemory = SqlEstimatedDeltaMemory;
                //joinTable.JoinHint = JoinHint.Loop;
                SqlEstimatedSize = estimatedCompSize * estimatedNodeUnitSize /
                                   nodeUnitCandidate.TreeRoot.TableRowCount;

                cost     = loopCost; //componentSize*Math.Log(nodeUnitCandidate.TreeRoot.EstimatedRows, 512);
                TableRef = new WParenthesisTableReference
                {
                    Table = new WQualifiedJoin
                    {
                        FirstTableRef  = TableRef,
                        SecondTableRef =
                            nodeUnitCandidate.ToTableReference(GetNodeRefName(nodeUnitCandidate.TreeRoot), metaData),
                        JoinCondition     = joinCondition,
                        QualifiedJoinType = QualifiedJoinType.Inner,
                        JoinHint          = JoinHint.Loop
                    }
                };
            }
            // Hash Join
            else
            {
                cost = hashCost;//componentSize + nodeUnitSize;
                WBooleanExpression adjustedJoincondition;
                double             adjustedSqlEstimatedSize;
                WTableReference    buildTableReference;
                WTableReference    probeTableReference;
                if (firstJoin)
                {
                    var nodeInComp = MaterializedNodeSplitCount.Keys.First(e => e != node);
                    if (nodeUnitSize < componentSize)
                    {
                        buildTableReference = AdjustEstimation(nodeUnitCandidate, GetNodeRefName(node), metaData, out adjustedJoincondition,
                                                               out adjustedSqlEstimatedSize);
                        probeTableReference     = TableRef;
                        TotalMemory             = DeltaMemory = nodeUnitSize;
                        SqlEstimatedTotalMemory = SqlEstimatedDeltaMemory = estimatedNodeUnitSize;
                        RightestTableRefSize    = nodeInComp.EstimatedRows;
                        RightestTableAlias      = GetNodeRefName(nodeInComp);
                    }
                    else
                    {
                        RightestTableRefSize = nodeInComp.EstimatedRows;
                        RightestTableAlias   = GetNodeRefName(nodeInComp);
                        buildTableReference  = AdjustEstimation(this, out adjustedJoincondition, out adjustedSqlEstimatedSize);
                        probeTableReference  =
                            nodeUnitCandidate.ToTableReference(GetNodeRefName(nodeUnitCandidate.TreeRoot), metaData);
                        TotalMemory             = DeltaMemory = componentSize;
                        SqlEstimatedTotalMemory = SqlEstimatedDeltaMemory = SqlEstimatedSize;
                        RightestTableRefSize    = nodeUnitCandidate.TreeRoot.EstimatedRows;
                        RightestTableAlias      = GetNodeRefName(node);
                    }
                }
                // Left Deep
                else if (componentSize * sizeFactor < nodeUnitSize)
                {
                    // Adjust estimation in sql server
                    buildTableReference = AdjustEstimation(this, out adjustedJoincondition, out adjustedSqlEstimatedSize);
                    probeTableReference =
                        nodeUnitCandidate.ToTableReference(GetNodeRefName(nodeUnitCandidate.TreeRoot), metaData);
                    var curDeltaMemory = componentSize;
                    TotalMemory = DeltaMemory + curDeltaMemory;
                    DeltaMemory = curDeltaMemory;
                    var curDeltaEstimateMemory = SqlEstimatedSize;
                    SqlEstimatedTotalMemory = SqlEstimatedDeltaMemory + curDeltaEstimateMemory;
                    SqlEstimatedDeltaMemory = curDeltaEstimateMemory;


                    RightestTableAlias   = GetNodeRefName(node);
                    RightestTableRefSize = nodeUnitCandidate.TreeRoot.EstimatedRows;
                }
                // Right Deep
                else
                {
                    buildTableReference = AdjustEstimation(nodeUnitCandidate, GetNodeRefName(node), metaData, out adjustedJoincondition,
                                                           out adjustedSqlEstimatedSize);
                    probeTableReference = TableRef;

                    TotalMemory             += nodeUnitSize;
                    DeltaMemory              = TotalMemory;
                    SqlEstimatedTotalMemory += estimatedNodeUnitSize;
                    SqlEstimatedDeltaMemory  = SqlEstimatedTotalMemory;
                }
                newCompEstSize *= adjustedSqlEstimatedSize;
                TableRef        = new WParenthesisTableReference
                {
                    Table =
                        new WQualifiedJoin
                    {
                        FirstTableRef     = buildTableReference,
                        SecondTableRef    = probeTableReference,
                        JoinCondition     = WBooleanBinaryExpression.Conjunction(joinCondition, adjustedJoincondition),
                        QualifiedJoinType = QualifiedJoinType.Inner,
                        JoinHint          = JoinHint.Hash
                    }
                };
                SqlEstimatedSize = newCompEstSize < 1.0 ? 1.0 : newCompEstSize;
            }

            //Update Size
            Cardinality *= nodeUnitActualSize * joinSelectivity;

            // Debug
#if DEBUG
            //foreach (var item in MaterializedNodeSplitCount.Where(e => e.Key != node))
            //{
            //    Trace.Write(item.Key.RefAlias + ",");
            //}
            //Trace.Write(node.RefAlias);
            //Trace.Write(" Size:" + Cardinality + " Cost:" + cost);
            //Trace.Write(" Method:" + ((TableRef as WParenthesisTableReference).Table as WQualifiedJoin).JoinHint);
            //Trace.WriteLine(" --> Total Cost:" + Cost);
#endif


            // Update Cost
            Cost += cost;
        }