예제 #1
0
        public List <WBooleanExpression> Invoke(WBooleanExpression expr)
        {
            this.normalizedList = new List <WBooleanExpression>();
            expr.Accept(this);

            return(this.normalizedList);
        }
예제 #2
0
 internal static WBooleanParenthesisExpression GetBooleanParenthesisExpr(WBooleanExpression booleanExpr)
 {
     return(new WBooleanParenthesisExpression()
     {
         Expression = booleanExpr
     });
 }
예제 #3
0
 public string Invoke(WBooleanExpression node, Dictionary <string, string> columnToTable)
 {
     _tableBind     = false;
     _columnToTable = columnToTable;
     node.Accept(this);
     return(_tableName);
 }
예제 #4
0
 public void Invoke(WBooleanExpression booleanExpression)
 {
     if (booleanExpression != null)
     {
         booleanExpression.Accept(this);
     }
 }
예제 #5
0
 internal static WWhereClause GetWhereClause(WBooleanExpression predicate)
 {
     return(new WWhereClause()
     {
         SearchCondition = predicate
     });
 }
        private void Attach(WBooleanExpression expr)
        {
            var table = _booleanTabRefVisitor.Invoke(expr);
            // Only expression who reference one table can be attached
            var tableName = table.Count == 1 ? table.First().Key : "";

            MatchEdge edge;
            MatchNode node;

            if (_graph.TryGetEdge(tableName, out edge))
            {
                if (edge.Predicates == null)
                {
                    edge.Predicates = new List <WBooleanExpression>();
                }
                edge.Predicates.Add(expr);
            }
            else if (_graph.TryGetNode(tableName, out node))
            {
                if (node.Predicates == null)
                {
                    node.Predicates = new List <WBooleanExpression>();
                }
                node.Predicates.Add(expr);
            }
            else
            {
                FailedToAssign.Add(expr);
            }
        }
        // <table name, properties referenced>
        public Dictionary <string, HashSet <string> > Invoke(WBooleanExpression expr)
        {
            _tableandPropertiesDict = new Dictionary <string, HashSet <string> >();
            expr.Accept(this);

            return(_tableandPropertiesDict);
        }
예제 #8
0
        internal static WBooleanExpression ConcatBooleanExpressionList(List <WBooleanExpression> booleanExprList,
                                                                       BooleanBinaryExpressionType type)
        {
            if (booleanExprList.Count == 1)
            {
                return(booleanExprList.First());
            }
            WBooleanExpression concatExpr = null;

            foreach (var booleanExpr in booleanExprList)
            {
                if (booleanExpr == null)
                {
                    continue;
                }
                WBooleanExpression newExpr = type == BooleanBinaryExpressionType.Or
                    ? GetBooleanParenthesisExpr(booleanExpr)
                    : booleanExpr;
                concatExpr = concatExpr == null ? booleanExpr
                                                : GetBooleanBinaryExpr(concatExpr, newExpr, type);
            }
            if (concatExpr == null)
            {
                return(null);
            }
            if (type == BooleanBinaryExpressionType.Or)
            {
                return(GetBooleanParenthesisExpr(concatExpr));
            }
            return(concatExpr);
        }
예제 #9
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);
 }
예제 #10
0
 internal void AddPredicate(WBooleanExpression newPredicate)
 {
     if (newPredicate == null)
     {
         return;
     }
     Predicates = Predicates == null ? newPredicate : SqlUtil.GetAndBooleanBinaryExpr(Predicates, newPredicate);
 }
예제 #11
0
        public Dictionary <string, string> Invoke(WBooleanExpression booleanExpression)
        {
            if (booleanExpression != null)
            {
                booleanExpression.Accept(this);
            }

            return(this.referencedProperties);
        }
예제 #12
0
 internal static WBooleanBinaryExpression GetBooleanBinaryExpr(WBooleanExpression firstExpr,
                                                               WBooleanExpression secondExpr, BooleanBinaryExpressionType type)
 {
     return(new WBooleanBinaryExpression()
     {
         BooleanExpressionType = type,
         FirstExpr = firstExpr,
         SecondExpr = secondExpr
     });
 }
예제 #13
0
        public int Invoke(
            WBooleanExpression booleanExpression)
        {
            runtimeFunctionCount = 0;

            if (booleanExpression != null)
            {
                booleanExpression.Accept(this);
            }

            return(runtimeFunctionCount);
        }
예제 #14
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);
 }
예제 #15
0
        internal void HasLabel(GremlinVariable lastVariable, List <object> values)
        {
            List <WBooleanExpression> booleanExprList = new List <WBooleanExpression>();

            foreach (var value in values)
            {
                WScalarExpression firstExpr  = lastVariable.GetVariableProperty(GremlinKeyword.Label).ToScalarExpression();
                WScalarExpression secondExpr = SqlUtil.GetValueExpr(value);
                booleanExprList.Add(SqlUtil.GetEqualBooleanComparisonExpr(firstExpr, secondExpr));
            }
            WBooleanExpression concatSql = SqlUtil.ConcatBooleanExprWithOr(booleanExprList);

            AddPredicate(SqlUtil.GetBooleanParenthesisExpr(concatSql));
        }
예제 #16
0
        private void Attach(WBooleanExpression expr)
        {
            var table = _bindTableVisitor.Invoke(expr, _columnTableMapping);

            MatchEdge edge, revEdge;
            MatchNode node;

            if (_graph.TryGetEdge(table, out edge))
            {
                if (edge.Predicates == null)
                {
                    edge.Predicates = new List <WBooleanExpression>();
                }
                edge.Predicates.Add(expr);

                if (_graph.ReversedEdgeDict.TryGetValue(edge.EdgeAlias, out revEdge))
                {
                    if (revEdge.Predicates == null)
                    {
                        revEdge.Predicates = new List <WBooleanExpression>();
                    }

                    // take care when an edge is using a default alias
                    var revExpr  = ObjectExtensions.Copy(expr);
                    var compExpr = revExpr as WBooleanComparisonExpression;
                    if (compExpr != null)
                    {
                        var columnExpr = compExpr.FirstExpr as WColumnReferenceExpression ?? compExpr.SecondExpr as WColumnReferenceExpression;
                        if (columnExpr != null)
                        {
                            var column = columnExpr.MultiPartIdentifier.Identifiers;
                            if (column.Count >= 2)
                            {
                                column[column.Count - 2].Value = revEdge.EdgeAlias;
                            }
                        }
                    }
                    revEdge.Predicates.Add(revExpr);
                }
            }
            else if (_graph.TryGetNode(table, out node))
            {
                if (node.Predicates == null)
                {
                    node.Predicates = new List <WBooleanExpression>();
                }
                node.Predicates.Add(expr);
            }
        }
 public void UpdateWherClause(WWhereClause whereClause, WBooleanExpression node)
 {
     if (whereClause.SearchCondition == null)
     {
         whereClause.SearchCondition = node;
     }
     else
     {
         whereClause.SearchCondition = new WBooleanBinaryExpression
         {
             FirstExpr             = whereClause.SearchCondition,
             SecondExpr            = node,
             BooleanExpressionType = BooleanBinaryExpressionType.And
         };
     }
 }
 /// <summary>
 /// Conjuncts two boolean expressions
 /// </summary>
 /// <param name="joinCondition">The first boolean expression</param>
 /// <param name="newCondition">The second boolean expression</param>
 /// <returns>The conjunctive boolean expression</returns>
 public static WBooleanExpression Conjunction(WBooleanExpression joinCondition, WBooleanExpression newCondition)
 {
     if (joinCondition == null)
     {
         return(newCondition);
     }
     if (newCondition == null)
     {
         return(joinCondition);
     }
     return(new WBooleanBinaryExpression
     {
         FirstExpr = joinCondition,
         SecondExpr = newCondition,
         BooleanExpressionType = BooleanBinaryExpressionType.And
     });
 }
예제 #19
0
        public bool TryAttachPredicate(WBooleanExpression predicate, Dictionary <string, HashSet <string> > tableColumnReferences)
        {
            // Attach fail if it is a cross-table predicate
            if (tableColumnReferences.Count > 1)
            {
                return(false);
            }

            MatchEdge edge;
            MatchNode node;
            bool      attachFlag = false;

            foreach (var tableColumnReference in tableColumnReferences)
            {
                var tableName  = tableColumnReference.Key;
                var properties = tableColumnReference.Value;

                if (TryGetEdge(tableName, out edge))
                {
                    if (edge.Predicates == null)
                    {
                        edge.Predicates = new List <WBooleanExpression>();
                    }
                    edge.Predicates.Add(predicate);
                    // Attach edge's propeties for later runtime evaluation
                    AttachProperties(new Dictionary <string, HashSet <string> > {
                        { tableName, properties }
                    });
                    attachFlag = true;
                }
                else if (TryGetNode(tableName, out node))
                {
                    if (node.Predicates == null)
                    {
                        node.Predicates = new List <WBooleanExpression>();
                    }
                    node.Predicates.Add(predicate);
                    AttachProperties(new Dictionary <string, HashSet <string> > {
                        { tableName, properties }
                    });
                    attachFlag = true;
                }
            }

            return(attachFlag);
        }
예제 #20
0
        /// <summary>
        /// Calculate the number used for adjusting the SQL Server estimation in the downsize function.
        /// </summary>
        /// <param name="component"></param>
        /// <param name="joinCondition"></param>
        private static WTableReference AdjustEstimation(MatchComponent component, out WBooleanExpression joinCondition, out double affectedSqlEstimatedSize)
        {
            const int       sizeFactor     = 10;
            int             estimateFactor = 0;
            double          size           = component.Cardinality;
            double          estimatedSize  = component.SqlEstimatedSize;
            double          shrinkSize     = component.RightestTableRefSize;
            WTableReference tableReference = component.TableRef;

            affectedSqlEstimatedSize = 1.0;
            joinCondition            = null;

            if (size > sizeFactor * estimatedSize)
            {
                estimateFactor = (int)Math.Ceiling(size / estimatedSize);
            }
            else if (sizeFactor * size < estimatedSize)
            {
                shrinkSize = 1.0 / (1 - Math.Pow((1 - 1.0 / shrinkSize), 1.5));
                if (estimatedSize < shrinkSize)
                {
                    affectedSqlEstimatedSize /= estimatedSize;
                    estimatedSize             = 1;
                }
                else
                {
                    affectedSqlEstimatedSize /= shrinkSize;
                    estimatedSize            /= shrinkSize;
                }
                estimateFactor = (int)Math.Ceiling(size / estimatedSize);
                joinCondition  = ConstructDownSizeJoinCondition(component.RightestTableAlias);
            }
            if (estimateFactor > 1)
            {
                double affectedUpSize;
                tableReference = ConstructUpSizeTableReference(tableReference, estimateFactor,
                                                               out affectedUpSize);
                affectedSqlEstimatedSize *= affectedUpSize;
            }
            return(tableReference);
        }
        private void Attach(WBooleanExpression expr)
        {
            var table = _bindTableVisitor.Invoke(expr, _columnTableMapping);

            MatchEdge edge;
            MatchNode node;

            if (_graph.TryGetEdge(table, out edge))
            {
                if (edge.Predicates == null)
                {
                    edge.Predicates = new List <WBooleanExpression>();
                }
                edge.Predicates.Add(expr);
            }
            else if (_graph.TryGetNode(table, out node))
            {
                if (node.Predicates == null)
                {
                    node.Predicates = new List <WBooleanExpression>();
                }
                node.Predicates.Add(expr);
            }
        }
예제 #22
0
 public PredicateLink(WBooleanExpression booleanExpression)
 {
     this.BooleanExpression = booleanExpression;
     this.LinkAlias         = booleanExpression.ToString();
 }
예제 #23
0
 public virtual void Visit(WBooleanExpression node)
 {
     node.AcceptChildren(this);
 }
예제 #24
0
 public void Invoke(WBooleanExpression booleanExpression)
 {
     booleanExpression?.Accept(this);
 }
예제 #25
0
        internal virtual void Not(GremlinToSqlContext currentContext, GremlinToSqlContext notContext)
        {
            WBooleanExpression booleanExpr = SqlUtil.GetNotExistPredicate(notContext.ToSelectQueryBlock());

            currentContext.AddPredicate(booleanExpr);
        }
예제 #26
0
        internal virtual void Where(GremlinToSqlContext currentContext, GremlinToSqlContext whereContext)
        {
            WBooleanExpression wherePredicate = whereContext.ToSqlBoolean();

            currentContext.AddPredicate(wherePredicate);
        }
예제 #27
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);
        }
예제 #28
0
        /// <summary>
        /// Calculate join costs and update components using optimal join method & order
        /// </summary>
        /// <param name="nodeUnitCandidate"></param>
        /// <param name="component"></param>
        /// <param name="nodeTable"></param>
        /// <param name="componentTable"></param>
        /// <param name="joinCondition"></param>
        /// <param name="nodeDegrees"></param>
        /// <param name="estimatedNodeUnitSize"></param>
        /// <param name="estimatedSelectivity"></param>
        /// <returns></returns>
        private static WTableReference GetPlanAndUpdateCost(
            OneHeightTree nodeUnitCandidate,
            MatchComponent component,
            WTableReference nodeTable,
            WTableReference componentTable,
            WBooleanExpression joinCondition,
            double nodeDegrees,
            double joinSelectivity,
            double estimatedNodeUnitSize,
            double estimatedSelectivity)
        {
            var nodeUnitSize      = nodeUnitCandidate.TreeRoot.EstimatedRows * nodeDegrees;
            var componentSize     = component.Size;
            var estimatedCompSize = component.EstimateSize;
            var cost = nodeUnitSize + componentSize;
            //var joinSelectivity =
            //    nodeWithJoinMapping.SelectivityProduct;
            //nodeWithJoinMapping.ExponentialSelevtivityProduct;

            WQualifiedJoin joinTable = new WQualifiedJoin
            {
                FirstTableRef     = componentTable,
                SecondTableRef    = nodeTable,
                JoinCondition     = joinCondition,
                QualifiedJoinType = QualifiedJoinType.Inner,
                JoinHint          = JoinHint.Hash
            };

            var node = nodeUnitCandidate.TreeRoot;

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


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



            //Update Size
            component.Size *= nodeUnitActualSize * joinSelectivity;

            // Update Cost
            component.Cost += cost;

            // Debug
#if DEBUG
            //Trace.Write(component.NodeUnits.Count+" ");
            //foreach (var n in component.NodeUnits.Where(e => e.Key != node.Node.ExposedName))
            //{
            //    Trace.Write(n.Value.NodeRefName);
            //}
            //Trace.Write(component.NodeUnits[node.Node.ExposedName].NodeRefName+" ");
            //Trace.Write(" "+(long)component.Cost+"   "+(long)component.Size);
            //Trace.Write("   ");
            //foreach (var item in component.PopulatedEdgesName)
            //{
            //    Trace.Write(item + " ");
            //}
            //Trace.Write("; ");
            //foreach (var unpopulatedEdge in component.UnpopulatedEdges)
            //{
            //    Trace.Write(unpopulatedEdge.Alias + " ");
            //}
            //Trace.WriteLine("");
#endif



            // Update TableRef
            // Only consider the size in the first join
            if (component.MaterializedNodeSplitCount.Count == 2 && component.MaterializedNodeSplitCount.All(e => e.Value == 0))
            {
                var nodeInComp = component.MaterializedNodeSplitCount.Keys.First(e => e != node);
                if (nodeUnitSize < componentSize)
                {
                    joinTable.FirstTableRef            = nodeTable;
                    joinTable.SecondTableRef           = componentTable;
                    component.TotalMemory              = component.DeltaMemory = nodeUnitSize;
                    component.EstimateTotalMemory      = component.EstimateDeltaMemory = estimatedNodeUnitSize;
                    component.RightestTableRefSize     = nodeInComp.EstimatedRows;
                    component.FatherOfRightestTableRef = new Tuple <WQualifiedJoin, String>(joinTable,
                                                                                            component.GetNodeRefName(nodeInComp));
                    AdjustEstimation(component, nodeTable, joinTable, nodeUnitSize, estimatedNodeUnitSize,
                                     nodeUnitCandidate.TreeRoot.EstimatedRows, new Tuple <WQualifiedJoin, string>(joinTable, component.GetNodeRefName(node)));
                }
                else
                {
                    component.TotalMemory              = component.DeltaMemory = componentSize;
                    component.EstimateTotalMemory      = component.EstimateDeltaMemory = component.EstimateSize;
                    component.RightestTableRefSize     = nodeUnitCandidate.TreeRoot.EstimatedRows;
                    component.FatherOfRightestTableRef = new Tuple <WQualifiedJoin, String>(joinTable, component.GetNodeRefName(node));
                    AdjustEstimation(component, componentTable, joinTable, componentSize, estimatedCompSize,
                                     nodeInComp.EstimatedRows, new Tuple <WQualifiedJoin, string>(joinTable, component.GetNodeRefName(nodeInComp)));
                }
            }
            else
            {
                double sizeFactor             = 5;//1000;
                double maxMemory              = 1e8;
                double loopJoinInnerThreshold = 10000;
                double loopJoinOuterThreshold = 1000000;


                // Left Deep
                if (componentSize * sizeFactor < nodeUnitSize)
                {
                    var curDeltaMemory = componentSize;
                    component.TotalMemory = component.DeltaMemory + curDeltaMemory;
                    component.DeltaMemory = curDeltaMemory;
                    var curDeltaEstimateMemory = component.EstimateSize;
                    component.EstimateTotalMemory = component.EstimateDeltaMemory + curDeltaEstimateMemory;
                    component.EstimateDeltaMemory = curDeltaEstimateMemory;

                    // Adjust estimation in sql server
                    AdjustEstimation(component, componentTable, joinTable, componentSize, estimatedCompSize,
                                     component.RightestTableRefSize, component.FatherOfRightestTableRef);
                    component.FatherOfRightestTableRef = new Tuple <WQualifiedJoin, string>(joinTable, component.GetNodeRefName(node));
                    component.RightestTableRefSize     = nodeUnitCandidate.TreeRoot.EstimatedRows;
                }
                else
                {
                    // Loop Join
                    if (
                        //((nodeUnitSize < loopJoinInnerThreshold /*&& componentSize < loopJoinOuterThreshold*/) || component.DeltaMemory + componentSize > maxMemory / 100) &&
                        ((nodeUnitSize < loopJoinInnerThreshold && componentSize < loopJoinOuterThreshold) ||
                         component.DeltaMemory + componentSize > maxMemory) &&
                        nodeUnitCandidate.MaterializedEdges.Count == 0)
                    {
                        component.TotalMemory         = component.DeltaMemory;
                        component.EstimateTotalMemory = component.EstimateDeltaMemory;
                        joinTable.JoinHint            = JoinHint.Loop;
                        component.EstimateSize        = estimatedCompSize * estimatedNodeUnitSize /
                                                        nodeUnitCandidate.TreeRoot.TableRowCount;
                    }
                    // Right Deep
                    else
                    {
                        joinTable.FirstTableRef  = nodeTable;
                        joinTable.SecondTableRef = componentTable;

                        AdjustEstimation(component, nodeTable, joinTable, nodeUnitSize, estimatedNodeUnitSize,
                                         node.EstimatedRows, new Tuple <WQualifiedJoin, string>(joinTable, component.GetNodeRefName(node)));

                        component.TotalMemory         += nodeUnitSize;
                        component.DeltaMemory          = component.TotalMemory;
                        component.EstimateTotalMemory += estimatedNodeUnitSize;
                        component.EstimateDeltaMemory  = component.EstimateTotalMemory;
                    }
                }
            }

            return(new WParenthesisTableReference
            {
                Table = joinTable
            });
        }
 public bool Invoke(WBooleanExpression node)
 {
     _referencedByNodeAndEdge = true;
     node.Accept(this);
     return(_referencedByNodeAndEdge);
 }
예제 #30
0
 private void Extract(WBooleanExpression expr)
 {
     this.normalizedList.Add(expr);
 }