Пример #1
0
        public Dictionary <string, string> GetColumnTableMapping(
            Dictionary <Tuple <string, string>, Dictionary <string, NodeColumns> > columnsOfNodeTables)
        {
            if (_columnTableAliasMapping == null)
            {
                _columnTableAliasMapping = new Dictionary <string, string>(StringComparer.CurrentCultureIgnoreCase);
                var duplicateColumns = new HashSet <string>();
                foreach (var kvp in NodeTableDictionary)
                {
                    var nodeTable = kvp.Value as WNamedTableReference;
                    if (nodeTable != null)
                    {
                        var nodeTableObjectName = nodeTable.TableObjectName;
                        var nodeTableTuple      = WNamedTableReference.SchemaNameToTuple(nodeTableObjectName);
                        foreach (
                            var property in
                            columnsOfNodeTables[nodeTableTuple].Where(e => e.Value.Role != WNodeTableColumnRole.Edge)
                            .Select(e => e.Key))
                        {
                            if (!_columnTableAliasMapping.ContainsKey(property.ToLower()))
                            {
                                _columnTableAliasMapping[property.ToLower()] = kvp.Key;
                            }
                            else
                            {
                                duplicateColumns.Add(property.ToLower());
                            }
                        }
                    }
                }

                foreach (var kvp in EdgeDictionary)
                {
                    var tuple = kvp.Value;
                    var sourceTableObjectName = tuple.Item1;
                    var edgeColumnReference   = tuple.Item2;
                    var soureNodeTableTuple   =
                        WNamedTableReference.SchemaNameToTuple(sourceTableObjectName);
                    var edgeProperties =
                        columnsOfNodeTables[soureNodeTableTuple][
                            edgeColumnReference.MultiPartIdentifier.Identifiers.Last().Value.ToLower()];
                    foreach (var attribute in edgeProperties.ColumnAttributes)
                    {
                        if (!_columnTableAliasMapping.ContainsKey(attribute.ToLower()))
                        {
                            _columnTableAliasMapping[attribute.ToLower()] = kvp.Key;
                        }
                        else
                        {
                            duplicateColumns.Add(attribute.ToLower());
                        }
                    }
                }
                foreach (var col in duplicateColumns)
                {
                    _columnTableAliasMapping.Remove(col);
                }
            }
            return(_columnTableAliasMapping);
        }
 /// <summary>
 /// Returns true if there are columns of a specific table referenced in a statement
 /// </summary>
 /// <param name="node">The query statement</param>
 /// <param name="tableName">the table for query</param>
 /// <param name="context">Sql context with table alias mapping</param>
 /// <param name="columnsOfNodeTables"></param>
 /// <param name="conn">A open Sql connection</param>
 /// <returns></returns>
 public bool Invoke(WSelectQueryBlock node, string tableName, WSqlTableContext context,
                    Dictionary <Tuple <string, string>, Dictionary <string, NodeColumns> > columnsOfNodeTables)
 {
     _tableExists        = false;
     _tableName          = tableName;
     _tableRef           = context[tableName] as WNamedTableReference;
     _columnTableMapping = context.GetColumnTableMapping(columnsOfNodeTables);
     node.Accept(this);
     return(_tableExists);
 }
 /// <summary>
 /// Returns true if there are columns of a specific table referenced in a statement
 /// </summary>
 /// <param name="node">The query statement</param>
 /// <param name="tableName">the table for query</param>
 /// <param name="context">Sql context with table alias mapping</param>
 /// <param name="columnsOfNodeTables"></param>
 /// <param name="conn">A open Sql connection</param>
 /// <returns></returns>
 public bool Invoke(WSelectQueryBlock node, string tableName, WSqlTableContext context,
     Dictionary<Tuple<string, string>, Dictionary<string, NodeColumns>> columnsOfNodeTables)
 {
     _tableExists = false;
     _tableName = tableName;
     _tableRef = context[tableName] as WNamedTableReference;
     _columnTableMapping = context.GetColumnToAliasMapping(columnsOfNodeTables);
     node.Accept(this);
     return _tableExists;
 }
Пример #4
0
 public override void Visit(WNamedTableReference node)
 {
     if (_nodeTables != null  &&
         !_nodeTables.Contains(WNamedTableReference.SchemaNameToTuple(node.TableObjectName)))
     {
         //throw new GraphViewException("Invalid Table " + node);
         return;
     }
     var name = node.Alias ?? node.TableObjectName.BaseIdentifier;
     _results.AddNodeTable(name.Value, node);
 }
        public override void Visit(WNamedTableReference node)
        {
            if (_nodeTables != null &&
                !_nodeTables.Contains(WNamedTableReference.SchemaNameToTuple(node.TableObjectName)))
            {
                //throw new GraphViewException("Invalid Table " + node);
                return;
            }
            var name = node.Alias ?? node.TableObjectName.BaseIdentifier;

            _results.AddNodeTable(name.Value, node);
        }
Пример #6
0
        //public virtual WSchemaObjectFunctionTableReference ToSchemaObjectFunction(string nodeAlias, GraphMetaData metaData)
        //{
        //    var edgeIdentifiers = EdgeColumn.MultiPartIdentifier.Identifiers;
        //    var edgeColIdentifier = edgeIdentifiers.Last();
        //    var edgeColName = edgeColIdentifier.Value;

        //    HashSet<string> nodeSet;
        //    if (!metaData.NodeViewMapping.TryGetValue(
        //        WNamedTableReference.SchemaNameToTuple(SourceNode.NodeTableObjectName), out nodeSet))
        //        nodeSet = null;
        //    NodeColumns columnInfo = metaData.ColumnsOfNodeTables[WNamedTableReference.SchemaNameToTuple(BindNodeTableObjName)][
        //        edgeColIdentifier.Value];
        //    EdgeInfo edgeInfo = columnInfo.EdgeInfo;
        //    List<Tuple<string, string>> edgeTuples = edgeInfo.EdgeColumns;
        //    var parameters = ConstructEdgeTvfParameters(nodeAlias, "", nodeSet, edgeTuples);

        //    //var isRevEdge = columnInfo.IsReversedEdge;
        //    //string refTableName = null, originalEdgeName = null;
        //    //if (isRevEdge)
        //    //{
        //    //    var index = edgeColName.IndexOf('_');
        //    //    refTableName = edgeColName.Substring(0, index);
        //    //    originalEdgeName = edgeColName.Substring(index + 1,
        //    //        edgeColName.Length - "Reversed".Length - index - 1);
        //    //}
        //    //var decoderSchemaName = isRevEdge ? columnInfo.RefTableSchema : BindNodeTableObjName.SchemaIdentifier.Value;
        //    //var decoderTableName = isRevEdge ? refTableName : BindNodeTableObjName.BaseIdentifier.Value;
        //    //var decoderEdgeName = isRevEdge ? originalEdgeName : EdgeColumn.MultiPartIdentifier.Identifiers.Last().Value;
        //    //var decoderStr = decoderSchemaName + "_" + decoderTableName + "_" + decoderEdgeName + "_Decoder";

        //    var decoderFunction = new Identifier
        //    {
        //        Value = edgeInfo.EdgeUdfPrefix + "_Decoder",
        //    };
        //    return new WSchemaObjectFunctionTableReference
        //    {
        //        SchemaObject = new WSchemaObjectName(
        //            new Identifier { Value = "dbo" },
        //            decoderFunction),
        //        Parameters = parameters,
        //        Alias = new Identifier
        //        {
        //            Value = EdgeAlias,
        //        }
        //    };
        //}

        /// <summary>
        /// Converts the edge to the table-valued function
        /// </summary>
        /// <param name="nodeAlias">Source node alias</param>
        /// <param name="dumbNode">Dumb node parameter alias</param>
        /// <param name="metaData">Meta data</param>
        /// <returns>A syntax tree node representing the table-valued function</returns>
        public virtual WSchemaObjectFunctionTableReference ToSchemaObjectFunction(string nodeAlias, string dumbNode, GraphMetaData metaData)
        {
            var edgeIdentifiers    = EdgeColumn.MultiPartIdentifier.Identifiers;
            var edgeColIdentifier  = edgeIdentifiers.Last();
            var edgeColName        = edgeColIdentifier.Value;
            var bindNodeTableTuple = WNamedTableReference.SchemaNameToTuple(BindNodeTableObjName);

            HashSet <string> nodeSet;

            if (!metaData.NodeViewMapping.TryGetValue(
                    WNamedTableReference.SchemaNameToTuple(SourceNode.NodeTableObjectName), out nodeSet))
            {
                nodeSet = null;
            }

            if (IsEdgeView && IsReversedEdge)
            {
                var sinkNodeTableTuple = WNamedTableReference.SchemaNameToTuple(SinkNode.NodeTableObjectName);
                var index = edgeColName.IndexOf(sinkNodeTableTuple.Item2, StringComparison.OrdinalIgnoreCase);
                index += sinkNodeTableTuple.Item2.Length;
                var originalEdgeViewName = edgeColName.Substring(index + 1,
                                                                 edgeColName.Length - "Reversed".Length - index - 1);
                edgeColName = bindNodeTableTuple.Item2 + "_" + originalEdgeViewName + "Reversed";
            }

            NodeColumns columnInfo =
                metaData.ColumnsOfNodeTables[WNamedTableReference.SchemaNameToTuple(BindNodeTableObjName)][
                    edgeColName];
            EdgeInfo edgeInfo = columnInfo.EdgeInfo;
            List <Tuple <string, string> > edgeTuples = edgeInfo.EdgeColumns;

            var parameters = ConstructEdgeTvfParameters(nodeAlias, dumbNode, nodeSet, edgeTuples);

            var decoderFunction = new Identifier
            {
                Value = edgeInfo.EdgeUdfPrefix + "_Decoder",
            };

            return(new WSchemaObjectFunctionTableReference
            {
                SchemaObject = new WSchemaObjectName(
                    new Identifier {
                    Value = "dbo"
                },
                    decoderFunction),
                Parameters = parameters,
                Alias = new Identifier
                {
                    Value = EdgeAlias,
                }
            });
        }
Пример #7
0
        public MatchComponent(MatchNode node) : this()
        {
            Nodes.Add(node);
            MaterializedNodeSplitCount[node] = 0;
            StatisticsDict[node]             = new ColumnStatistics {
                Selectivity = 1.0 / node.TableRowCount
            };

            Size         *= node.EstimatedRows;
            EstimateSize *= node.EstimatedRows;
            TableRef      = new WNamedTableReference
            {
                Alias = new Identifier {
                    Value = node.RefAlias
                },
                TableObjectName = node.TableObjectName
            };
        }
Пример #8
0
        public WTableReference ToTableReference(string nodeAlias, GraphMetaData metaData)
        {
            // Constructs table reference
            WTableReference nodeTable = new WNamedTableReference
            {
                Alias = new Identifier {
                    Value = nodeAlias
                },
                TableObjectName = TreeRoot.NodeTableObjectName
            };

            nodeTable = MaterializedEdges.Aggregate(nodeTable, (current, edge) => new WUnqualifiedJoin
            {
                FirstTableRef       = current,
                SecondTableRef      = edge.ToSchemaObjectFunction(nodeAlias, metaData),
                UnqualifiedJoinType = UnqualifiedJoinType.CrossApply,
            });
            return(nodeTable);
        }
Пример #9
0
        // We firstly think every node are isolated, and we will find subgraphs later
        internal string AddTable(WNamedTableReference table)
        {
            string alias = table.Alias.Value;

            this.TableInputDependency[alias] = new HashSet <string>();
            MatchNode matchNode = new MatchNode()
            {
                NodeAlias        = alias,
                Neighbors        = new List <MatchEdge>(),
                ReverseNeighbors = new List <MatchEdge>(),
                DanglingEdges    = new List <MatchEdge>(),
                Predicates       = new List <WBooleanExpression>(),
                Properties       = new HashSet <string>()
            };
            ConnectedComponent subgraph = new ConnectedComponent();

            subgraph.Nodes[alias] = matchNode;
            this.GraphPattern.ConnectedSubgraphs.Add(subgraph);
            matchNode.Position = this.TableInputDependency.Count;
            return(alias);
        }
Пример #10
0
        /// <summary>
        /// Converts the edge to the table-valued function
        /// </summary>
        /// <param name="nodeAlias">Source node alias</param>
        /// <param name="metaData">Meta data</param>
        /// <returns>A syntax tree node representing the table-valued function</returns>
        public virtual WSchemaObjectFunctionTableReference ToSchemaObjectFunction(string nodeAlias, GraphMetaData metaData)
        {
            var edgeIdentifiers   = EdgeColumn.MultiPartIdentifier.Identifiers;
            var edgeColIdentifier = edgeIdentifiers.Last();

            HashSet <string> nodeSet;

            if (!metaData.NodeViewMapping.TryGetValue(
                    WNamedTableReference.SchemaNameToTuple(SourceNode.NodeTableObjectName), out nodeSet))
            {
                nodeSet = null;
            }
            EdgeInfo edgeInfo =
                metaData.ColumnsOfNodeTables[WNamedTableReference.SchemaNameToTuple(BindNodeTableObjName)][
                    edgeColIdentifier.Value].EdgeInfo;
            List <Tuple <string, string> > edgeTuples = edgeInfo.EdgeColumns;
            var parameters = ConstructEdgeTvfParameters(nodeAlias, nodeSet, edgeTuples);

            var decoderFunction = new Identifier
            {
                Value = BindNodeTableObjName.SchemaIdentifier.Value + '_' +
                        BindNodeTableObjName.BaseIdentifier.Value + '_' +
                        EdgeColumn.MultiPartIdentifier.Identifiers.Last().Value + '_' +
                        "Decoder"
            };

            return(new WSchemaObjectFunctionTableReference
            {
                SchemaObject = new WSchemaObjectName(
                    new Identifier {
                    Value = "dbo"
                },
                    decoderFunction),
                Parameters = parameters,
                Alias = new Identifier
                {
                    Value = EdgeAlias,
                }
            });
        }
Пример #11
0
 public override void Visit(WNamedTableReference node)
 {
     vertexTableList.Add(node);
 }
Пример #12
0
        private WTableReference ParseTableReference(TableReference tabRef)
        {
            if (tabRef == null)
            {
                return null;
            }
            var tabRefWithAlias = tabRef as TableReferenceWithAlias;
            if (tabRefWithAlias!=null && tabRefWithAlias.Alias!=null &&
                 GraphViewKeywords._keywords.Contains(tabRefWithAlias.Alias.Value))
            {
                var token = _tokens[tabRefWithAlias.Alias.FirstTokenIndex];
                throw new SyntaxErrorException(token.Line, tabRefWithAlias.Alias.Value,
                    "System restricted Name cannot be used");
            }
            switch (tabRef.GetType().Name)
            {
                case "NamedTableReference":
                    {
                        var oref = tabRef as NamedTableReference;
                        if (oref.SchemaObject.BaseIdentifier.QuoteType == QuoteType.NotQuoted &&
                            (oref.SchemaObject.BaseIdentifier.Value[0] == '@' ||
                             oref.SchemaObject.BaseIdentifier.Value[0] == '#'))
                        {
                            var pref = new WSpecialNamedTableReference
                            {
                                Alias = oref.Alias,
                                TableHints = new List<WTableHint>(),
                                FirstTokenIndex = oref.FirstTokenIndex,
                                LastTokenIndex = oref.LastTokenIndex,
                                TableObjectName = ParseSchemaObjectName(oref.SchemaObject),
                            };

                            if (oref.TableHints != null)
                            {
                                foreach (var hint in oref.TableHints)
                                    pref.TableHints.Add(ParseTableHint(hint));
                            }

                            return pref;
                        }
                        else
                        {
                            var pref = new WNamedTableReference
                            {
                                Alias = oref.Alias,
                                TableHints = new List<WTableHint>(),
                                FirstTokenIndex = oref.FirstTokenIndex,
                                LastTokenIndex = oref.LastTokenIndex,
                                TableObjectName = ParseSchemaObjectName(oref.SchemaObject),
                            };

                            if (oref.TableHints != null)
                            {
                                foreach (var hint in oref.TableHints)
                                    pref.TableHints.Add(ParseTableHint(hint));
                            }

                            return pref;
                        }
                    }
                case "QueryDerivedTable":
                    {
                        var oref = tabRef as QueryDerivedTable;
                        var pref = new WQueryDerivedTable
                        {
                            QueryExpr = ParseSelectQueryStatement(oref.QueryExpression),
                            Alias = oref.Alias,
                            Columns = oref.Columns,
                            FirstTokenIndex = oref.FirstTokenIndex,
                            LastTokenIndex = oref.LastTokenIndex,
                        };

                        return pref;
                    }
                case "SchemaObjectFunctionTableReference":
                    {
                        var oref = tabRef as SchemaObjectFunctionTableReference;
                        var pref = new WSchemaObjectFunctionTableReference
                        {
                            Alias = oref.Alias,
                            Columns = oref.Columns,
                            SchemaObject = ParseSchemaObjectName(oref.SchemaObject),
                            FirstTokenIndex = oref.FirstTokenIndex,
                            LastTokenIndex = oref.LastTokenIndex
                        };
                        if (oref.Parameters == null)
                            return pref;
                        pref.Parameters = new List<WScalarExpression>();
                        foreach (var param in oref.Parameters)
                            pref.Parameters.Add(ParseScalarExpression(param));
                        return pref;
                    }
                case "QualifiedJoin":
                    {
                        var oref = tabRef as QualifiedJoin;
                        var pref = new WQualifiedJoin
                        {
                            FirstTableRef = ParseTableReference(oref.FirstTableReference),
                            SecondTableRef = ParseTableReference(oref.SecondTableReference),
                            QualifiedJoinType = oref.QualifiedJoinType,
                            JoinHint = oref.JoinHint,
                            JoinCondition = ParseBooleanExpression(oref.SearchCondition),
                            FirstTokenIndex = oref.FirstTokenIndex,
                            LastTokenIndex = oref.LastTokenIndex,
                        };

                        return pref;
                    }
                case "UnqualifiedJoin":
                    {
                        var oref = tabRef as UnqualifiedJoin;
                        var pref = new WUnqualifiedJoin
                        {
                            FirstTableRef = ParseTableReference(oref.FirstTableReference),
                            SecondTableRef = ParseTableReference(oref.SecondTableReference),
                            UnqualifiedJoinType = oref.UnqualifiedJoinType,
                            FirstTokenIndex = oref.FirstTokenIndex,
                            LastTokenIndex = oref.LastTokenIndex,
                        };
                        return pref;
                    }
                case "JoinParenthesisTableReference":
                    {
                        var ptab = tabRef as JoinParenthesisTableReference;

                        var wptab = new WParenthesisTableReference
                        {
                            Table = ParseTableReference(ptab.Join),
                            FirstTokenIndex = ptab.FirstTokenIndex,
                            LastTokenIndex = ptab.LastTokenIndex,
                        };

                        return wptab;
                    }
                default:
                    return null;
            }
        }
Пример #13
0
 public virtual void Visit(WNamedTableReference node)
 {
     node.AcceptChildren(this);
 }
Пример #14
0
 public override void Visit(WNamedTableReference node)
 {
     blocks.Last().AddTable(node);
 }
Пример #15
0
 public virtual void Visit(WNamedTableReference node)
 {
     node.AcceptChildren(this);
 }
Пример #16
0
        public MatchComponent(MatchNode node):this()
        {
            Nodes.Add(node);
            MaterializedNodeSplitCount[node] = 0;
            StatisticsDict[node] = new ColumnStatistics{Selectivity = 1.0/node.TableRowCount};

            Size *= node.EstimatedRows;
            EstimateSize *= node.EstimatedRows;
            TableRef = new WNamedTableReference
            {
                Alias = new Identifier { Value = node.RefAlias},
                TableObjectName = node.TableObjectName
            };
        }
Пример #17
0
        /// <summary>
        /// Constructs parameters for the edge table-valued function when translation the MATCH clause
        /// </summary>
        /// <param name="nodeAlias">Source node alias</param>
        /// <param name="dumbNode">Dumb node parameter alias</param>
        /// <param name="nodeTableNameSet">Node table names mapping to the source node of the edge.
        /// If null, the source node is mapped to a physical table in the syntax tree. Otherewise,
        /// the source node is mapped to a node view</param>
        /// <param name="edgeNameTuples">A tuple (Node table name, Edge column name) mapping to the edge.
        /// If null, the edge is mapped to an edge column in a physical node table. Ohterwise,
        /// the edge is mapped to an edge view</param>
        /// <returns>Parameters in the table-valued function</returns>
        protected List <WScalarExpression> ConstructEdgeTvfParameters(string nodeAlias, string dumbNode,
                                                                      HashSet <string> nodeTableNameSet = null, List <Tuple <string, string> > edgeNameTuples = null)
        {
            var        edgeIdentifiers   = EdgeColumn.MultiPartIdentifier.Identifiers;
            var        edgeColIdentifier = edgeIdentifiers.Last();
            Identifier srcNodeIdentifier = new Identifier {
                Value = nodeAlias
            };
            List <WScalarExpression> parameters = new List <WScalarExpression>();

            // The source is a physical node
            if (nodeTableNameSet == null)
            {
                // The edge is a physical edge
                if (edgeNameTuples == null)
                {
                    parameters.Add(new WColumnReferenceExpression
                    {
                        MultiPartIdentifier =
                            new WMultiPartIdentifier(srcNodeIdentifier, edgeColIdentifier)
                    });
                    parameters.Add(new WColumnReferenceExpression
                    {
                        MultiPartIdentifier =
                            new WMultiPartIdentifier(srcNodeIdentifier,
                                                     new Identifier {
                            Value = edgeColIdentifier.Value + "DeleteCol"
                        })
                    });
                }
                // The edge is an edge view
                else
                {
                    var sourceTableName = WNamedTableReference.SchemaNameToTuple(SourceNode.NodeTableObjectName).Item2;
                    foreach (var column in edgeNameTuples)
                    {
                        if (sourceTableName.Equals(column.Item1, StringComparison.OrdinalIgnoreCase))
                        {
                            Identifier includedEdgeColumnIdentifier = new Identifier {
                                Value = column.Item2
                            };
                            parameters.Add(new WColumnReferenceExpression
                            {
                                MultiPartIdentifier =
                                    new WMultiPartIdentifier(srcNodeIdentifier, includedEdgeColumnIdentifier)
                            });
                            parameters.Add(new WColumnReferenceExpression
                            {
                                MultiPartIdentifier =
                                    new WMultiPartIdentifier(srcNodeIdentifier,
                                                             new Identifier {
                                    Value = includedEdgeColumnIdentifier.Value + "DeleteCol"
                                })
                            });
                        }
                        else
                        {
                            parameters.Add(new WValueExpression {
                                Value = "null"
                            });
                            parameters.Add(new WValueExpression {
                                Value = "null"
                            });
                        }
                    }
                }
            }
            // The source is a node view
            else
            {
                // The edge is a physical edge
                if (edgeNameTuples == null)
                {
                    string     srcTableName = BindNodeTableObjName.BaseIdentifier.Value;
                    Identifier nodeViewEdgeColIdentifier = new Identifier
                    {
                        Value = srcTableName + "_" + edgeColIdentifier.Value
                    };
                    parameters.Add(new WColumnReferenceExpression
                    {
                        MultiPartIdentifier =
                            new WMultiPartIdentifier(srcNodeIdentifier, nodeViewEdgeColIdentifier)
                    });
                    parameters.Add(new WColumnReferenceExpression
                    {
                        MultiPartIdentifier =
                            new WMultiPartIdentifier(srcNodeIdentifier,
                                                     new Identifier {
                            Value = nodeViewEdgeColIdentifier.Value + "DeleteCol"
                        })
                    });
                }
                // The edge is an edge view
                else
                {
                    foreach (var column in edgeNameTuples)
                    {
                        if (nodeTableNameSet.Contains(column.Item1))
                        {
                            Identifier includedEdgeColumnIdentifier = new Identifier
                            {
                                Value = column.Item1 + "_" + column.Item2
                            };
                            parameters.Add(new WColumnReferenceExpression
                            {
                                MultiPartIdentifier =
                                    new WMultiPartIdentifier(srcNodeIdentifier, includedEdgeColumnIdentifier)
                            });
                            parameters.Add(new WColumnReferenceExpression
                            {
                                MultiPartIdentifier =
                                    new WMultiPartIdentifier(srcNodeIdentifier,
                                                             new Identifier {
                                    Value = includedEdgeColumnIdentifier.Value + "DeleteCol"
                                })
                            });
                        }
                        else
                        {
                            parameters.Add(new WValueExpression {
                                Value = "null"
                            });
                            parameters.Add(new WValueExpression {
                                Value = "null"
                            });
                        }
                    }
                }
            }
            // dumbNode == NULL -> pathFunction, no dumb alias
            if (dumbNode != null)
            {
                if (string.IsNullOrEmpty(dumbNode))
                {
                    parameters.Add(new WValueExpression {
                        Value = "0"
                    });
                }
                else
                {
                    parameters.Add(new WColumnReferenceExpression
                    {
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {
                            Value = dumbNode
                        },
                            new Identifier {
                            Value = "GlobalNodeId"
                        }
                            ),
                    });
                }
            }

            return(parameters);
        }
Пример #18
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;
        }
Пример #19
0
        /// <summary>
        /// Converts the edge to the table-valued function
        /// </summary>
        /// <param name="nodeAlias">Source node alias</param>
        /// <param name="dumbNode"></param>
        /// <param name="metaData">Meta data</param>
        /// <returns>A syntax tree node representing the table-valued function</returns>
        public override WSchemaObjectFunctionTableReference ToSchemaObjectFunction(string nodeAlias, string dumbNode, GraphMetaData metaData)
        {
            var edgeIdentifiers   = EdgeColumn.MultiPartIdentifier.Identifiers;
            var edgeColIdentifier = edgeIdentifiers.Last();
            HashSet <string> nodeSet;

            if (!metaData.NodeViewMapping.TryGetValue(
                    WNamedTableReference.SchemaNameToTuple(SourceNode.NodeTableObjectName), out nodeSet))
            {
                nodeSet = null;
            }
            var sourceNodeColumns =
                metaData.ColumnsOfNodeTables[WNamedTableReference.SchemaNameToTuple(BindNodeTableObjName)];
            var edgeInfo = sourceNodeColumns[edgeColIdentifier.Value].EdgeInfo;
            List <Tuple <string, string> > edgeTuples = edgeInfo.EdgeColumns;
            var parameters = ConstructEdgeTvfParameters(nodeAlias, null, nodeSet, edgeTuples);

            Identifier decoderFunction;

            if (ReferencePathInfo)
            {
                decoderFunction = new Identifier
                {
                    Value = BindNodeTableObjName.SchemaIdentifier.Value + '_' +
                            BindNodeTableObjName.BaseIdentifier.Value + '_' +
                            EdgeColumn.MultiPartIdentifier.Identifiers.Last().Value + '_' +
                            "bfsPathWithMessage"
                };
                // Node view
                if (nodeSet != null)
                {
                    parameters.Insert(0, new WColumnReferenceExpression
                    {
                        MultiPartIdentifier =
                            new WMultiPartIdentifier(new Identifier()
                        {
                            Value = SourceNode.RefAlias
                        },
                                                     new Identifier()
                        {
                            Value = "_NodeId"
                        })
                    });
                    parameters.Insert(0, new WColumnReferenceExpression
                    {
                        MultiPartIdentifier =
                            new WMultiPartIdentifier(new Identifier()
                        {
                            Value = SourceNode.RefAlias
                        },
                                                     new Identifier()
                        {
                            Value = "_NodeType"
                        })
                    });
                }
                else
                {
                    string nodeIdName =
                        sourceNodeColumns.FirstOrDefault(e => e.Value.Role == WNodeTableColumnRole.NodeId).Key;
                    if (string.IsNullOrEmpty(nodeIdName))
                    {
                        parameters.Insert(0, new WValueExpression {
                            Value = "null"
                        });
                    }
                    else
                    {
                        parameters.Insert(0, new WColumnReferenceExpression
                        {
                            MultiPartIdentifier =
                                new WMultiPartIdentifier(new Identifier()
                            {
                                Value = SourceNode.RefAlias
                            },
                                                         new Identifier()
                            {
                                Value = nodeIdName
                            })
                        });
                    }
                    parameters.Insert(0,
                                      new WValueExpression {
                        Value = BindNodeTableObjName.BaseIdentifier.Value, SingleQuoted = true
                    });
                }
            }
            else
            {
                decoderFunction = new Identifier
                {
                    Value = BindNodeTableObjName.SchemaIdentifier.Value + '_' +
                            BindNodeTableObjName.BaseIdentifier.Value + '_' +
                            EdgeColumn.MultiPartIdentifier.Identifiers.Last().Value + '_' +
                            "bfsPath"
                };
            }
            parameters.Insert(0, new WValueExpression {
                Value = MaxLength.ToString()
            });
            parameters.Insert(0, new WValueExpression {
                Value = MinLength.ToString()
            });
            parameters.Insert(0,
                              new WColumnReferenceExpression
            {
                MultiPartIdentifier =
                    new WMultiPartIdentifier(new[] { new Identifier {
                                                         Value = nodeAlias
                                                     }, new Identifier {
                                                         Value = "GlobalNodeId"
                                                     }, })
            });
            var attributes = edgeInfo.ColumnAttributes;

            if (AttributeValueDict == null)
            {
                WValueExpression nullExpression = new WValueExpression {
                    Value = "null"
                };
                for (int i = 0; i < attributes.Count; i++)
                {
                    parameters.Add(nullExpression);
                }
            }
            else
            {
                foreach (var attribute in attributes)
                {
                    string value;
                    var    valueExpression = new WValueExpression
                    {
                        Value = AttributeValueDict.TryGetValue(attribute, out value) ? value : "null"
                    };

                    parameters.Add(valueExpression);
                }
            }
            return(new WSchemaObjectFunctionTableReference
            {
                SchemaObject = new WSchemaObjectName(
                    new Identifier {
                    Value = "dbo"
                },
                    decoderFunction),
                Parameters = parameters,
                Alias = new Identifier
                {
                    Value = EdgeAlias,
                }
            });
        }
Пример #20
0
 public WTableReference ToTableReference(string nodeAlias,GraphMetaData metaData)
 {
     // Constructs table reference
     WTableReference nodeTable = new WNamedTableReference
     {
         Alias = new Identifier { Value = nodeAlias },
         TableObjectName = TreeRoot.NodeTableObjectName
     };
     nodeTable = MaterializedEdges.Aggregate(nodeTable, (current, edge) => new WUnqualifiedJoin
     {
         FirstTableRef = current,
         SecondTableRef = edge.ToSchemaObjectFunction(nodeAlias, metaData),
         UnqualifiedJoinType = UnqualifiedJoinType.CrossApply,
     });
     return nodeTable;
 }
Пример #21
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);
        }
Пример #22
0
        //private double _edgeDegrees = -1;
        //public double EdgeDegrees
        //{
        //    get
        //    {
        //        if (_edgeDegrees < 0)
        //        {
        //            double matEdgeDegrees = MaterializedEdges.Aggregate(1.0, (cur, next) => cur*next.AverageDegree);
        //            double unMatEdgeDegrees = UnmaterializedEdges.Aggregate(1.0, (cur, next) => cur * next.AverageDegree);
        //            _edgeDegrees = unMatEdgeDegrees*matEdgeDegrees;
        //        }
        //        return _edgeDegrees;
        //    }
        //}
        //private double _sqlEstimatedEdgeDegrees = -1;
        //public double SqlEstimatedEdgeDegrees
        //{
        //    get
        //    {
        //        if (_sqlEstimatedEdgeDegrees < 0)
        //        {
        //            _sqlEstimatedEdgeDegrees = Math.Pow(1000, MaterializedEdges.Count + UnmaterializedEdges.Count);
        //        }
        //        return _sqlEstimatedEdgeDegrees;
        //    }
        //}
        //public WTableReference ToTableReference(string nodeAlias, GraphMetaData metaData)
        //{
        //    // Constructs table reference
        //    WTableReference nodeTable = new WNamedTableReference
        //    {
        //        Alias = new Identifier { Value = nodeAlias },
        //        TableObjectName = TreeRoot.NodeTableObjectName
        //    };
        //    nodeTable = MaterializedEdges.Aggregate(nodeTable, (current, edge) => new WUnqualifiedJoin
        //    {
        //        FirstTableRef = current,
        //        SecondTableRef = edge.ToSchemaObjectFunction(nodeAlias, metaData),
        //        UnqualifiedJoinType = UnqualifiedJoinType.CrossApply,
        //    });
        //    return nodeTable;
        //}
        public WTableReference ToTableReference(string nodeAlias, string dumbNode, GraphMetaData metaData)
        {
            // Constructs table reference
            WTableReference nodeTable = new WNamedTableReference
            {
                Alias = new Identifier { Value = nodeAlias },
                TableObjectName = TreeRoot.NodeTableObjectName
            };
            if (PreMatOutgoingEdges != null && PreMatOutgoingEdges.Any())
            {
                nodeTable = PreMatOutgoingEdges.Aggregate(nodeTable, (current, edge) => new WUnqualifiedJoin
                {
                    FirstTableRef = current,
                    SecondTableRef = edge.ToSchemaObjectFunction(nodeAlias, dumbNode, metaData),
                    UnqualifiedJoinType = UnqualifiedJoinType.CrossApply,
                });
            }

            return nodeTable;
        }
Пример #23
0
        public MatchComponent(MatchNode node)
            : this()
        {
            Nodes.Add(node);
            MaterializedNodeSplitCount[node] = 0;
            //SinkNodeStatisticsDict[node] = new Statistics ();
            Cardinality *= node.EstimatedRows;
            SqlEstimatedSize *= node.EstimatedRows;
            TableRef = new WNamedTableReference
            {
                Alias = new Identifier { Value = node.RefAlias},
                TableObjectName = node.NodeTableObjectName
            };
            LastTableAlias = node.RefAlias;
            LastTable = null;

            foreach (var edge in node.Neighbors)
            {
                var edgeList = UnmaterializedNodeMapping.GetOrCreate(edge.SinkNode);
                edgeList.Add(edge);
            }
        }