public override void Visit(WColumnReferenceExpression node) { var column = node.MultiPartIdentifier.Identifiers; if (column.Count >= 2) { var tableName = column.First().Value; var propertyName = ""; HashSet <string> properties; if (!_tableandPropertiesDict.TryGetValue(tableName, out properties)) { _tableandPropertiesDict[tableName] = new HashSet <string>(); } propertyName += column[1].Value; for (var i = 2; i < column.Count; i++) { propertyName += "." + column[i].ToString(); } _tableandPropertiesDict[tableName].Add(propertyName); } else { throw new GraphViewException("Identifier " + column.ToString() + " should be bound to a table."); } }
public override void Visit(WColumnReferenceExpression node) { if (!_referencedByNodeAndEdge) { return; } var column = node.MultiPartIdentifier.Identifiers; string tableAlias = ""; if (column.Count >= 2) { tableAlias = column[column.Count - 2].Value; } else { var columnName = column.Last().Value; if ((_columnTableMapping.ContainsKey(columnName))) { tableAlias = _columnTableMapping[columnName]; } } if (!_graph.ContainsNode(tableAlias)) { _referencedByNodeAndEdge = false; } }
public override void Visit(WColumnReferenceExpression columnReference) { IList <Identifier> columnList = columnReference.MultiPartIdentifier.Identifiers; string propertyName = ""; if (columnList.Count == 2) { string originalColumnName = columnList[1].Value; if (originalColumnName.Equals(GremlinKeyword.NodeID, StringComparison.InvariantCultureIgnoreCase) || originalColumnName.Equals(GremlinKeyword.Label, StringComparison.InvariantCultureIgnoreCase)) { return; } string encodeName = EncodeString(originalColumnName); referencedProperties[encodeName] = originalColumnName; columnList[0].Value = encodeName; columnList[1].Value = NormalizeWColumnReferenceExpressionVisitor.ReservedPropertyKeyName; } else { throw new QueryCompilationException("Identifier " + columnList.ToString() + " should be bound to a table."); } }
public override void Visit(WColumnReferenceExpression columnReference) { IList <Identifier> columnList = columnReference.MultiPartIdentifier.Identifiers; string propertyName = ""; if (columnList.Count == 2) { string tableName = columnList[0].Value; if (this.skipTableNames.Contains(tableName)) { return; } string originalColumnName = columnList[1].Value; if (this.flatProperties.Contains(originalColumnName)) { return; } columnReference.AddIdentifier("*"); columnReference.AddIdentifier("_value"); } else { throw new QueryCompilationException("Identifier " + columnList + " should be bound to a table."); } }
public override void Visit(WColumnReferenceExpression columnReference) { IList <Identifier> columnList = columnReference.MultiPartIdentifier.Identifiers; string propertyName = ""; if (columnList.Count == 2) { string originalColumnName = columnList[1].Value; if (originalColumnName.Equals(GremlinKeyword.NodeID) || originalColumnName.Equals(GremlinKeyword.Label)) { return; } string encodeName = EncodeString(originalColumnName); referencedProperties[encodeName] = originalColumnName; columnList[0].Value = encodeName; columnList[1].Value = GraphViewKeywords.KW_PROPERTY_VALUE; } else { throw new QueryCompilationException("Identifier " + columnList.ToString() + " should be bound to a table."); } }
// // E_0.|id => E_0['|id'] // public override void Visit(WColumnReferenceExpression node) { if (this.NeedsConvertion.Count == 0 || this.NeedsConvertion.Contains(node.TableReference)) { node.MultiPartIdentifier = new DMultiPartIdentifier(node.MultiPartIdentifier); } }
internal static WColumnReferenceExpression CreateColumnExpression(string tableName, string columnName) { var columnExpr = new WColumnReferenceExpression { ColumnType = ColumnType.Regular }; if (tableName != null) { var tabIdent = new Identifier { Value = tableName }; columnExpr.Add(tabIdent); } if (columnName == null) { return(columnExpr); } var colIdent = new Identifier { Value = columnName }; columnExpr.Add(colIdent); return(columnExpr); }
public override void Visit(WColumnReferenceExpression node) { if (node.MultiPartIdentifier == null) return; var column = node.MultiPartIdentifier.Identifiers; if (column.Count >= 2) { var columnName = column[column.Count - 2].Value; if (_edgeTableReferenceDict.ContainsKey(columnName)) { if (_edgeTableReferenceDict[columnName].Count > 1) throw new GraphViewException("Ambiguious Table Reference"); column[column.Count - 2].Value = _edgeTableReferenceDict[columnName].First(); } } //else //{ // var columnName = column.Last().Value; // if (_columnTableDict.ContainsKey(columnName)) // { // column.Insert(0, new Identifier { Value = _columnTableDict[columnName] }); // } //} base.Visit(node); }
public override void Visit(WColumnReferenceExpression columnReference) { IList <Identifier> columnList = columnReference.MultiPartIdentifier.Identifiers; string propertyName = ""; if (columnList.Count == 2) { string tableName = columnList[0].Value; if (this.skipTableNames.Contains(tableName)) { return; } string originalColumnName = columnList[1].Value; if (this.flatProperties.Contains(originalColumnName)) { return; } string encodeName = EncodeString(originalColumnName); this.referencedProperties[encodeName] = originalColumnName; columnList[0].Value = encodeName; columnList[1].Value = DocumentDBKeywords.KW_PROPERTY_VALUE; } else { throw new QueryCompilationException("Identifier " + columnList + " should be bound to a table."); } }
/// <summary> /// Generate the Table-Valued Function by the edge given the node alias /// </summary> /// <param name="edge"></param> /// <param name="nodeAlias"></param> /// <returns></returns> private static WTableReference EdgeToTableReference(MatchEdge edge, string nodeAlias) { var edgeColumn = edge.EdgeColumn; var edgeIdentifiers = edge.EdgeColumn.MultiPartIdentifier.Identifiers; if (nodeAlias != edgeIdentifiers.First().Value) { var identifiers = new List <Identifier>(edgeIdentifiers); identifiers.RemoveAt(0); identifiers.Insert(0, new Identifier { Value = nodeAlias }); edgeColumn = new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier { Identifiers = identifiers } }; } var columnName = edgeIdentifiers.Last().Value; var deColIdentifiers = new Identifier[] { edgeColumn.MultiPartIdentifier.Identifiers.First(), new Identifier { Value = columnName + "DeleteCol" } }; var decoderFunction = new Identifier { Value = edge.SourceNode.TableObjectName.SchemaIdentifier.Value + '_' + edge.SourceNode.TableObjectName.BaseIdentifier.Value + '_' + columnName + '_' + "Decoder", }; var tableRef = new WSchemaObjectFunctionTableReference { SchemaObject = new WSchemaObjectName( new Identifier { Value = "dbo" }, decoderFunction), Parameters = new List <WScalarExpression> { edgeColumn, new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(deColIdentifiers) } }, Alias = new Identifier { Value = edge.EdgeAlias, } }; return(tableRef); }
public override void Visit(WColumnReferenceExpression node) { var columnExpr = node.MultiPartIdentifier.Identifiers; if (columnExpr.Count >= 2) _tables.Add(columnExpr[columnExpr.Count - 2].Value.ToLower(CultureInfo.CurrentCulture)); else _unboundColumns.Add(columnExpr.Last().Value.ToLower(CultureInfo.CurrentCulture)); }
public override void Visit(WColumnReferenceExpression node) { string nodeStr = node.MultiPartIdentifier != null ? node.MultiPartIdentifier.ToString() : ""; this.dfsStack.Push(nodeStr); }
/// <summary> /// Adds a new field to the raw records when a new execution operator is added to the execution plan. /// </summary> /// <param name="tableAlias"></param> /// <param name="columnName"></param> /// <param name="type"></param> public void AddField(string tableAlias, string columnName, ColumnGraphType type) { int index = RawRecordLayout.Count; WColumnReferenceExpression colRef = new WColumnReferenceExpression(tableAlias, columnName); colRef.ColumnGraphType = type; RawRecordLayout[colRef] = index; }
internal static void GetPathStepListAndByFuncList( QueryCompilationContext context, GraphViewCommand command, IList <WScalarExpression> parameters, out List <Tuple <ScalarFunction, bool, HashSet <string> > > pathStepList, out List <ScalarFunction> byFuncList) { // // If the boolean value is true, then it's a subPath to be unfolded // pathStepList = new List <Tuple <ScalarFunction, bool, HashSet <string> > >(); byFuncList = new List <ScalarFunction>(); QueryCompilationContext byInitContext = new QueryCompilationContext(context); byInitContext.ClearField(); byInitContext.AddField(GremlinKeyword.Compose1TableDefaultName, GremlinKeyword.TableDefaultColumnName, ColumnGraphType.Value); foreach (WScalarExpression expression in parameters) { WFunctionCall basicStep = expression as WFunctionCall; WValueExpression stepLabel = expression as WValueExpression; WColumnReferenceExpression subPath = expression as WColumnReferenceExpression; WScalarSubquery byFunc = expression as WScalarSubquery; if (basicStep != null) { pathStepList.Add( new Tuple <ScalarFunction, bool, HashSet <string> >( basicStep.CompileToFunction(context, command), false, new HashSet <string>())); } else if (stepLabel != null) { if (!pathStepList.Any()) { pathStepList.Add(new Tuple <ScalarFunction, bool, HashSet <string> >(null, false, new HashSet <string>())); } pathStepList.Last().Item3.Add(stepLabel.Value); } else if (subPath != null) { pathStepList.Add( new Tuple <ScalarFunction, bool, HashSet <string> >( subPath.CompileToFunction(context, command), true, new HashSet <string>())); } else if (byFunc != null) { byFuncList.Add(byFunc.CompileToFunction(byInitContext, command)); } else { throw new QueryCompilationException( "The parameter of WPathTableReference can only be a WFunctionCall/WValueExpression/WColumnReferenceExpression/WScalarSubquery."); } } }
public override void Visit(WColumnReferenceExpression node) { if (_tableExists) { return; } if (node.MultiPartIdentifier == null) { return; } var columnIdentifiers = node.MultiPartIdentifier.Identifiers; var columnName = columnIdentifiers.Last().Value; switch (columnIdentifiers.Count) { // unbound column, no need to check because all unbounded columns have been bounded to a table when constructing the graph case 1: if (_columnTableMapping.ContainsKey(columnName) && String.Equals(_columnTableMapping[columnName], _tableName, StringComparison.CurrentCultureIgnoreCase)) { _tableExists = true; } break; // column referencd by exposed name case 2: var tableExposedName = columnIdentifiers[0].Value; if (String.Equals(tableExposedName, _tableName, StringComparison.CurrentCultureIgnoreCase)) { _tableExists = true; } break; // column referencd by complete table name default: var flag = true; var index1 = columnIdentifiers.Count - 2; var index2 = _tableRef.TableObjectName.Count - 1; for (; index1 >= 0 && index2 >= 0; --index1, --index2) { if (String.Equals(columnIdentifiers[index1].Value, _tableRef.TableObjectName[index2].Value, StringComparison.CurrentCultureIgnoreCase)) { continue; } flag = false; break; } _tableExists = flag; break; } }
/// <summary> /// Given a column reference, returns its offset in the raw records produced by the SQL statement. /// </summary> /// <param name="columnReference"></param> /// <returns></returns> public int LocateColumnReference(WColumnReferenceExpression columnReference) { if (RawRecordLayout.ContainsKey(columnReference)) { return(RawRecordLayout[columnReference]); } else { throw new QueryCompilationException(string.Format("Column reference {0} cannot be located in the raw records in the current execution pipeline.", columnReference.ToString(""))); } }
public override void Visit(WColumnReferenceExpression node) { var columnExpr = node.MultiPartIdentifier.Identifiers; if (columnExpr.Count >= 2) { _tables.Add(columnExpr[columnExpr.Count - 2].Value.ToLower(CultureInfo.CurrentCulture)); } else { _unboundColumns.Add(columnExpr.Last().Value.ToLower(CultureInfo.CurrentCulture)); } }
/// <summary> /// Given a column reference, i.e., the composite key of (table alias, column name), /// return its offset in raw records produced by the SQL statement. /// </summary> /// <param name="tableAlias">Table alias</param> /// <param name="columnName">Column name</param> /// <returns>The offset of the column reference in the raw records</returns> public int LocateColumnReference(string tableAlias, string columnName) { WColumnReferenceExpression targetName = new WColumnReferenceExpression(tableAlias, columnName); if (RawRecordLayout.ContainsKey(targetName)) { return(RawRecordLayout[targetName]); } else { throw new QueryCompilationException(string.Format("Column reference {0}.{1} cannot be located in the raw records in the current execution pipeline.", tableAlias, columnName)); } }
public override void Visit(WColumnReferenceExpression columnReference) { var key = columnReference.TableReference; var value = columnReference.ColumnName; foreach (var item in map) { if (item.Key.TableReference.Equals(key) && item.Key.ColumnName.Equals(value)) { columnReference.MultiPartIdentifier.Identifiers[0].Value = GremlinKeyword.RepeatInitalTableName; columnReference.MultiPartIdentifier.Identifiers[1].Value = item.Value; } } }
public override void Visit(WColumnReferenceExpression columnReference) { string key = columnReference.TableReference; string value = columnReference.ColumnName; foreach (KeyValuePair <Tuple <string, string>, Tuple <string, string> > item in this.Map) { if (item.Key.Item1.Equals(key) && item.Key.Item2.Equals(value)) { columnReference.MultiPartIdentifier.Identifiers[0].Value = item.Value.Item1; columnReference.MultiPartIdentifier.Identifiers[1].Value = item.Value.Item2; } } }
public override void Visit(WColumnReferenceExpression columnReference) { var key = columnReference.MultiPartIdentifier.Identifiers[0].Value; var value = columnReference.MultiPartIdentifier.Identifiers[1].Value; foreach (var item in _map) { if (item.Key.GremlinVariable.GetVariableName().Equals(key) && item.Key.VariableProperty.Equals(value)) { columnReference.MultiPartIdentifier.Identifiers[0].Value = "R"; columnReference.MultiPartIdentifier.Identifiers[1].Value = item.Value; } } }
public override void Visit(WColumnReferenceExpression node) { var column = node.MultiPartIdentifier.Identifiers; if (column.Count >= 2) { Bind(column[column.Count - 2].Value); } else { var columnName = column.Last().Value; Bind(_columnToTable.ContainsKey(columnName) ? _columnToTable[columnName] : ""); } }
public override void Visit(WColumnReferenceExpression node) { var column = node.MultiPartIdentifier.Identifiers; if (column.Count >= 2 && _tableName.Equals(column.First().Value, StringComparison.OrdinalIgnoreCase)) { column.First().Value = _tableName; } else { node.MultiPartIdentifier.Identifiers.Insert(0, new Identifier { Value = _tableName }); } }
internal GraphViewExecutionOperator Compile2(QueryCompilationContext context, GraphViewConnection dbConnection) { WColumnReferenceExpression dropTargetParameter = Parameters[0] as WColumnReferenceExpression; Debug.Assert(dropTargetParameter != null, "dropTargetParameter != null"); int dropTargetIndex = context.LocateColumnReference(dropTargetParameter); // // A new DropOperator which drops target based on its runtime type // DropNodeOperator dropOp = new DropNodeOperator(context.CurrentExecutionOperator, dbConnection, dropTargetIndex); context.CurrentExecutionOperator = dropOp; return(dropOp); }
public override void Visit(WColumnReferenceExpression node) { var column = node.MultiPartIdentifier.Identifiers; if (column.Count >= 2) { Bind(column[column.Count - 2].Value); } else { var columnName = column.Last().Value; Bind(_columnToTable.ContainsKey(columnName) ? _columnToTable[columnName] : ""); } }
public override void Visit(WColumnReferenceExpression node) { string columnName = node.ColumnName; string tableAlias = node.TableReference; if (tableAlias == null) { throw new QueryCompilationException("Identifier " + columnName + " must be bound to a table alias."); } if (accessedColumns.ContainsKey(tableAlias)) { accessedColumns[tableAlias].Add(columnName); } else { _isOnlyTargetTableReferenced = false; } }
public override bool Equals(object obj) { WColumnReferenceExpression colRef = obj as WColumnReferenceExpression; if (colRef == null || MultiPartIdentifier.Count != colRef.MultiPartIdentifier.Count) { return(false); } for (int i = 0; i < MultiPartIdentifier.Count; i++) { if (MultiPartIdentifier[i].Value != colRef.MultiPartIdentifier[i].Value) { return(false); } } return(true); }
public override void Visit(WColumnReferenceExpression node) { if (_tableExists) return; if (node.MultiPartIdentifier == null) return; var columnIdentifiers = node.MultiPartIdentifier.Identifiers; var columnName = columnIdentifiers.Last().Value; switch (columnIdentifiers.Count) { // unbound column, no need to check because all unbounded columns have been bounded to a table when constructing the graph case 1: if (_columnTableMapping.ContainsKey(columnName) && String.Equals(_columnTableMapping[columnName], _tableName, StringComparison.OrdinalIgnoreCase)) _tableExists = true; break; // column referencd by exposed name case 2: var tableExposedName = columnIdentifiers[0].Value; if (String.Equals(tableExposedName, _tableName, StringComparison.OrdinalIgnoreCase)) _tableExists = true; break; // column referencd by complete table name default: var flag = true; var index1 = columnIdentifiers.Count - 2; var index2 = _tableRef.TableObjectName.Count - 1; for (; index1 >= 0 && index2 >= 0; --index1, --index2) { if (String.Equals(columnIdentifiers[index1].Value, _tableRef.TableObjectName[index2].Value, StringComparison.OrdinalIgnoreCase)) continue; flag = false; break; } _tableExists = flag; break; } }
internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection) { WColumnReferenceExpression updateParameter = this.Parameters[0] as WColumnReferenceExpression; int updateIndex = context.LocateColumnReference(updateParameter); var propertiesList = new List <WPropertyExpression>(); for (int i = 1; i < this.Parameters.Count; ++i) { propertiesList.Add((WPropertyExpression)this.Parameters[i]); #if DEBUG ((WPropertyExpression)this.Parameters[i]).Value.ToJValue(); #endif } UpdatePropertiesOperator updateOp = new UpdatePropertiesOperator( context.CurrentExecutionOperator, dbConnection, updateIndex, propertiesList); context.CurrentExecutionOperator = updateOp; return(updateOp); }
/// <summary> /// Adds a new field to the raw records when a new execution operator is added to the execution plan. /// </summary> /// <param name="tableAlias"></param> /// <param name="columnName"></param> /// <param name="type"></param> /// <param name="insertAtFront"></param> public void AddField(string tableAlias, string columnName, ColumnGraphType type, bool insertAtFront = false) { WColumnReferenceExpression colRef = new WColumnReferenceExpression(tableAlias, columnName); colRef.ColumnGraphType = type; if (insertAtFront) { foreach (WColumnReferenceExpression column in this.RawRecordLayout.Keys.ToList()) { ++this.RawRecordLayout[column]; if (this.ParentContextRawRecordLayout != null && this.ParentContextRawRecordLayout.ContainsKey(column)) { ++this.ParentContextRawRecordLayout[column]; } } this.RawRecordLayout[colRef] = 0; } else { int index = this.RawRecordLayout.Count; this.RawRecordLayout[colRef] = index; } }
internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewCommand command) { WColumnReferenceExpression updateParameter = this.Parameters[0] as WColumnReferenceExpression; int updateIndex = context.LocateColumnReference(updateParameter); List <PropertyTuple> propertiesList = new List <PropertyTuple>(); for (int i = 1; i < this.Parameters.Count; ++i) { WPropertyExpression property = this.Parameters[i] as WPropertyExpression; if (property.Value is WValueExpression) { WValueExpression value = property.Value as WValueExpression; Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> > meta = new Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> >(); foreach (KeyValuePair <WValueExpression, WScalarExpression> pair in property.MetaProperties) { string name = pair.Key.Value; if (pair.Value is WValueExpression) { WValueExpression metaValue = pair.Value as WValueExpression; meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(metaValue.ToStringField(), null)); } else { WScalarSubquery metaScalarSubquery = pair.Value as WScalarSubquery; ScalarSubqueryFunction metaValueFunction = (ScalarSubqueryFunction)metaScalarSubquery.CompileToFunction(context, command); meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(null, metaValueFunction)); } } PropertyTuple valueProperty = new PropertyTuple(property.Cardinality, property.Key.Value, value.ToStringField(), meta); propertiesList.Add(valueProperty); } else { WScalarSubquery scalarSubquery = property.Value as WScalarSubquery; ScalarSubqueryFunction valueFunction = (ScalarSubqueryFunction)scalarSubquery.CompileToFunction(context, command); Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> > meta = new Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> >(); foreach (KeyValuePair <WValueExpression, WScalarExpression> pair in property.MetaProperties) { string name = pair.Key.Value; if (pair.Value is WValueExpression) { WValueExpression metaValue = pair.Value as WValueExpression; meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(metaValue.ToStringField(), null)); } else { WScalarSubquery metaScalarSubquery = pair.Value as WScalarSubquery; ScalarSubqueryFunction metaValueFunction = (ScalarSubqueryFunction)metaScalarSubquery.CompileToFunction(context, command); meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(null, metaValueFunction)); } } PropertyTuple valueProperty = new PropertyTuple(property.Cardinality, property.Key.Value, valueFunction, meta); propertiesList.Add(valueProperty); } } UpdatePropertiesOperator updateOp = new UpdatePropertiesOperator( context.CurrentExecutionOperator, command, updateIndex, propertiesList); context.CurrentExecutionOperator = updateOp; return(updateOp); }
/// <summary> /// Given a node / TVF, a traversalLink and backwardEdges, try to find all predicates that can be evaluated /// </summary> /// <param name="node"></param> /// <param name="traversalLink"></param> /// <param name="backwardEdges"></param> /// <param name="predicateLinksAccessedTableAliases"></param> private List <Tuple <PredicateLink, int> > FindPredicates( CompileNode node, CompileLink traversalLink, List <Tuple <MatchEdge, int> > backwardEdges, List <Tuple <PredicateLink, HashSet <string> > > predicateLinksAccessedTableAliases) { // Record temporary aliases and predicates HashSet <string> temporaryAliases = new HashSet <string>(this.ExistingNodesAndEdges); HashSet <string> temporaryPredicates = new HashSet <string>(this.ExistingPredicateLinks); List <Tuple <PredicateLink, int> > forwardLinks = new List <Tuple <PredicateLink, int> >(); // priority = 1 // retrieve traversalLink and add predicates if (traversalLink != null && !this.ExistingNodesAndEdges.Contains(traversalLink.LinkAlias)) { // Find predicates that can be evaluated after retrieving this traversalLink if (traversalLink is MatchEdge) { temporaryAliases.Add(traversalLink.LinkAlias); } else if (traversalLink is PredicateLink) { temporaryPredicates.Add(traversalLink.LinkAlias); } else { throw new QueryCompilationException("Cannot support " + traversalLink + " as a traversal link or an edge"); } foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2)) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 1)); } } // Make sure the all existing edges and this traversalLink are consistent // Because all existing edges are consistent, we just need make one exstring edge and this traversalLink consistent MatchNode matchNode = node as MatchNode; WColumnReferenceExpression nodeColumnReferenceExprFromTraversalLink = GetNodeColumnReferenceExprFromLink(traversalLink); WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(matchNode, this.ExistingNodesAndEdges); if (nodeColumnReferenceExprFromTraversalLink != null && nodeColumnReferenceExprFromAnExistingEdge != null) { forwardLinks.Add( new Tuple <PredicateLink, int>( new PredicateLink( SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromTraversalLink, nodeColumnReferenceExprFromAnExistingEdge)), 1)); } } // priority = 2 // retrieve node and some edges and add predicates temporaryAliases.Add(node.NodeAlias); foreach (Tuple <MatchEdge, int> tuple in backwardEdges) { if (tuple.Item2 == 2) { temporaryAliases.Add(tuple.Item1.LinkAlias); MatchNode otherNode = tuple.Item1.SinkNode; WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge = null; WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges); if (nodeColumnReferenceExprFromAnExistingEdge != null) { foreach (MatchEdge edge in otherNode.Neighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.ReverseNeighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.DanglingEdges) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } } // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent if (nodeColumnReferenceExprFromBackwardEdge != null && nodeColumnReferenceExprFromAnExistingEdge != null) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add( new Tuple <PredicateLink, int>( new PredicateLink( SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge, nodeColumnReferenceExprFromAnExistingEdge)), 2)); } } } // Check predicates foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2)) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 2)); } } // priority = 3 // retrieve another edges and add predicates foreach (Tuple <MatchEdge, int> tuple in backwardEdges) { if (tuple.Item2 == 3) { temporaryAliases.Add(tuple.Item1.LinkAlias); MatchNode otherNode = tuple.Item1.SinkNode; WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge = null; WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges); if (nodeColumnReferenceExprFromAnExistingEdge != null) { foreach (MatchEdge edge in otherNode.Neighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.ReverseNeighbors) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } if (nodeColumnReferenceExprFromBackwardEdge == null) { foreach (MatchEdge edge in otherNode.DanglingEdges) { if (edge.LinkAlias == tuple.Item1.LinkAlias) { nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge); break; } } } } // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent if (nodeColumnReferenceExprFromBackwardEdge != null && nodeColumnReferenceExprFromAnExistingEdge != null) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add( new Tuple <PredicateLink, int>( new PredicateLink( SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge, nodeColumnReferenceExprFromAnExistingEdge)), 3)); } } } // Check predicates foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases) { if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) && temporaryAliases.IsSupersetOf(tuple.Item2)) { temporaryPredicates.Add(tuple.Item1.LinkAlias); forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 3)); } } return(forwardLinks); }
private WBooleanExpression ConstructJoinCondition( CandidateJoinUnit candidateTree, IMatchJoinStatisticsCalculator statisticsCalculator, GraphMetaData metaData, Dictionary<Tuple<string, bool>, Statistics> srcNodeStatisticsDict, out double preJoinSelectivity, out double postJoinSelectivity, out double sqlEstimatedJoinSelectivity) { const double sizeThreshold = 1e8; const int loopJoinFactorThreshold = 20; preJoinSelectivity = 1.0; postJoinSelectivity = 1.0; sqlEstimatedJoinSelectivity = 1.0; var firstJoin = MaterializedNodeSplitCount.Count == 1; MatchNode firstNode = null; if (firstJoin) firstNode = Nodes.First(); var root = candidateTree.TreeRoot; WBooleanExpression joinCondition = null; WBooleanExpression whereCondition = null; string nodeName = root.RefAlias; if (!Nodes.Contains(root)) Nodes.Add(root); MaterializedNodeSplitCount[root] = 0; var inEdges = candidateTree.PreMatIncomingEdges.Select( e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Pre, e)) .Union( candidateTree.PostMatIncomingEdges.Select( e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Post, e))) .ToList(); var outEdges = candidateTree.PreMatOutgoingEdges.Select( e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Pre, e)) .Union( candidateTree.PostMatOutgoingEdges.Select( e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Post, e))) .ToList(); var densityList = new List<double>(); var inPostCount = 0; var outPostCount = 0; if (inEdges.Any()) { UnmaterializedNodeMapping.Remove(root); //joinSelectivity *= 1.0 / root.TableRowCount; Statistics statistics = null; Statistics srcNodeStat = null; foreach (var t in inEdges) { var order = t.Item1; var edge = t.Item2; var globalNodeIdRef = new WColumnReferenceExpression { ColumnType = ColumnType.Regular, MultiPartIdentifier = new WMultiPartIdentifier( new Identifier {Value = nodeName}, new Identifier {Value = "GlobalNodeId"} ) }; var newCondition = new WBooleanComparisonExpression { FirstExpr = new WColumnReferenceExpression { ColumnType = ColumnType.Regular, MultiPartIdentifier = new WMultiPartIdentifier( new Identifier {Value = edge.EdgeAlias}, new Identifier {Value = "Sink"} ), }, SecondExpr = order == MaterializedOrder.Post && inPostCount > 0 ? new WBinaryExpression { ExpressionType = BinaryExpressionType.Add, FirstExpr = globalNodeIdRef, SecondExpr = new WValueExpression { SingleQuoted = false, Value = "0", } } : (WScalarExpression)globalNodeIdRef, ComparisonType = BooleanComparisonType.Equals }; EdgeMaterilizedDict[edge] = true; double selectivity; statistics = Statistics.UpdateHistogram(statistics, edge.Statistics, out selectivity); if (order == MaterializedOrder.Pre) { preJoinSelectivity *= selectivity; joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition, newCondition); } else { ++inPostCount; postJoinSelectivity *= selectivity; whereCondition = WBooleanBinaryExpression.Conjunction(whereCondition, newCondition); } if (firstJoin) { double srcNodeSelectivity; srcNodeStat = Statistics.UpdateHistogram(srcNodeStat, srcNodeStatisticsDict[new Tuple<string, bool>(edge.EdgeAlias, edge.IsReversedEdge)], out srcNodeSelectivity); } densityList.Add(root.GlobalNodeIdDensity); } if (firstJoin) SinkNodeStatisticsDict[firstNode] = srcNodeStat; SinkNodeStatisticsDict[root] = statistics; } if (candidateTree.JoinHint == JoinHint.Loop) { var size = Cardinality*candidateTree.PreMatIncomingEdges.Select(e => e.AverageDegree) .Aggregate(1.0, (cur, next) => cur*next)*preJoinSelectivity; if (size >= sizeThreshold && size > root.EstimatedRows * loopJoinFactorThreshold) candidateTree.JoinHint = JoinHint.Hash; } if (outEdges.Any()) { foreach (var t in outEdges) { var order = t.Item1; var edge = t.Item2; var sinkNode = edge.SinkNode; var globalNodeIdRef = new WColumnReferenceExpression { ColumnType = ColumnType.Regular, MultiPartIdentifier = new WMultiPartIdentifier( new Identifier {Value = sinkNode.RefAlias}, new Identifier {Value = "GlobalNodeId"} ) }; var newCondition = new WBooleanComparisonExpression { FirstExpr = new WColumnReferenceExpression { ColumnType = ColumnType.Regular, MultiPartIdentifier = new WMultiPartIdentifier( new Identifier {Value = edge.EdgeAlias}, new Identifier {Value = "Sink"} ), }, SecondExpr = order == MaterializedOrder.Post && outPostCount > 0 ? new WBinaryExpression { ExpressionType = BinaryExpressionType.Add, FirstExpr = globalNodeIdRef, SecondExpr = new WValueExpression { SingleQuoted = false, Value = "0", } } : (WScalarExpression)globalNodeIdRef, ComparisonType = BooleanComparisonType.Equals }; EdgeMaterilizedDict[edge] = true; Statistics sinkNodeStatistics; if (!SinkNodeStatisticsDict.TryGetValue(sinkNode, out sinkNodeStatistics)) { sinkNodeStatistics = null; //joinSelectivity *= 1.0 / sinkNode.TableRowCount; } double selectivity; var statistics = Statistics.UpdateHistogram(sinkNodeStatistics, edge.Statistics, out selectivity); if (order == MaterializedOrder.Pre) { preJoinSelectivity *= selectivity; joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition, newCondition); } else { ++outPostCount; postJoinSelectivity *= selectivity; whereCondition = WBooleanBinaryExpression.Conjunction(whereCondition, newCondition); } SinkNodeStatisticsDict[sinkNode] = statistics; densityList.Add(sinkNode.GlobalNodeIdDensity); } } var unmatEdges = candidateTree.UnmaterializedEdges; foreach (var unmatEdge in unmatEdges) { EdgeMaterilizedDict[unmatEdge] = false;; var unmatNodeInEdges = UnmaterializedNodeMapping.GetOrCreate(unmatEdge.SinkNode); unmatNodeInEdges.Add(unmatEdge); } densityList.Sort(); for (int i = densityList.Count - 1; i >= 0; i--) { sqlEstimatedJoinSelectivity *= Math.Sqrt(sqlEstimatedJoinSelectivity) * densityList[i]; } WhereCondition = WBooleanBinaryExpression.Conjunction(WhereCondition, whereCondition); return joinCondition; }
/// <summary> /// Generate the Table-Valued Function by the edge given the node alias /// </summary> /// <param name="edge"></param> /// <param name="nodeAlias"></param> /// <returns></returns> private static WTableReference EdgeToTableReference(MatchEdge edge, string nodeAlias) { var edgeColumn = edge.EdgeColumn; var edgeIdentifiers = edge.EdgeColumn.MultiPartIdentifier.Identifiers; if (nodeAlias != edgeIdentifiers.First().Value) { var identifiers = new List<Identifier>(edgeIdentifiers); identifiers.RemoveAt(0); identifiers.Insert(0, new Identifier { Value = nodeAlias }); edgeColumn = new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier { Identifiers = identifiers } }; } var columnName = edgeIdentifiers.Last().Value; var deColIdentifiers = new Identifier[] { edgeColumn.MultiPartIdentifier.Identifiers.First(), new Identifier {Value = columnName + "DeleteCol"} }; var decoderFunction = new Identifier { Value = edge.SourceNode.TableObjectName.SchemaIdentifier.Value + '_' + edge.SourceNode.TableObjectName.BaseIdentifier.Value + '_' + columnName + '_' + "Decoder", }; var tableRef = new WSchemaObjectFunctionTableReference { SchemaObject = new WSchemaObjectName( new Identifier {Value = "dbo"}, decoderFunction), Parameters = new List<WScalarExpression> { edgeColumn, new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(deColIdentifiers) } }, Alias = new Identifier { Value = edge.EdgeAlias, } }; return tableRef; }
public override void Visit(WColumnReferenceExpression node) { if (!_referencedByNodeAndEdge) return; var column = node.MultiPartIdentifier.Identifiers; string tableAlias = ""; if (column.Count >= 2) { tableAlias = column[column.Count - 2].Value; } else { var columnName = column.Last().Value; if ((_columnTableMapping.ContainsKey(columnName))) { tableAlias = _columnTableMapping[columnName]; } } if (!_graph.ContainsNode(tableAlias)) { _referencedByNodeAndEdge = false; } }
public override void Visit(WColumnReferenceExpression node) { if (node.MultiPartIdentifier == null) { return; } var column = node.MultiPartIdentifier.Identifiers; var number = column.Count; if (number >= 3) { var tableName = column[number - 2]; var columName = column[number - 1]; column.Clear(); column.Insert(0, tableName); column.Insert(1, columName); } }
public override void Visit(WSelectQueryBlock node) { if (node.SelectElements == null || node.SelectElements.Count < 2) { throw new GraphViewException("Numbers of select elements mismatch."); } var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression; if (sourceTableScalar == null) throw new GraphViewException("Source node id should be a scalar expression."); var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression; if (sourceTableColumn == null) throw new GraphViewException("Source node id column should be a column reference expression."); var sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value; var sourceNodeIdExpr = new WColumnReferenceExpression(); foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers) sourceNodeIdExpr.Add(identifier); sourceNodeIdExpr.AddIdentifier("GlobalNodeId"); if (node.SelectElements.Count < 2) throw new GraphViewException("Source and Sink tables should be specified in select elements."); if (node.GroupByClause != null) { throw new GraphViewException("GROUP BY clause is not allowed in INSERT EDGE statement."); } var collectVarVisitor = new CollectVariableVisitor(); var context = collectVarVisitor.Invoke(node); WColumnReferenceExpression sinkNodeIdExpr = null; for (var index = 1; index < node.SelectElements.Count; ++index) { var element = node.SelectElements[index] as WSelectScalarExpression; if (element == null) throw new GraphViewException("Edge property should be a scalar expression."); //sink table if (index == 1) { var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression; if (sinkTableColumn == null) throw new GraphViewException("Sink node id column should be a column reference expression."); var sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value; _sinkTable = context[sinkTableName]; sinkNodeIdExpr = new WColumnReferenceExpression(); foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers) sinkNodeIdExpr.Add(identifier); sinkNodeIdExpr.AddIdentifier("GlobalNodeId"); } else { _edgeProperties.Add(element.SelectExpr); } } var sourceTable = context[sourceTableName] as WNamedTableReference; if (sourceTable == null) { throw new GraphViewException("Source table of INSERT EDGE statement should be a named table reference."); } var sourceNodeId = new WSelectScalarExpression { SelectExpr = sourceNodeIdExpr, ColumnName = "src", }; var sinkNodeId = new WSelectScalarExpression { SelectExpr = sinkNodeIdExpr, ColumnName = "sink" }; var elements = new List<WSelectElement> { sourceNodeId, sinkNodeId }; var result = new WCommonTableExpression { ExpressionName = new Identifier {Value = _tempTableName}, QueryExpression = new WSelectQueryBlock { FromClause = node.FromClause, WhereClause = new WWhereClause { SearchCondition = node.WhereClause.SearchCondition }, HavingClause = node.HavingClause, OrderByClause = node.OrderByClause, TopRowFilter = node.TopRowFilter, UniqueRowFilter = node.UniqueRowFilter, SelectElements = elements, MatchClause = node.MatchClause } }; _result = result; }
private WCommonTableExpression ConstructDeleteEdgeSelect(WSelectQueryBlock node, string edgeAlias, string tempTableName ,out WTableReference sinkTable, out WTableReference sourceTable) { sourceTable = null; sinkTable = null; var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression; if (sourceTableScalar == null) return null; var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression; if (sourceTableColumn == null) return null; var sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value; var sourceNodeIdExpr = new WColumnReferenceExpression(); foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers) sourceNodeIdExpr.Add(identifier); sourceNodeIdExpr.AddIdentifier("GlobalNodeId"); var collectVarVisitor = new CollectVariableVisitor(); var context = collectVarVisitor.Invoke(node); if (!context.NodeTableDictionary.Any()) { throw new GraphViewException("Missing From Clause in Delete Edge statement"); } WColumnReferenceExpression sinkNodeIdExpr = null; sourceTable = context[sourceTableName]; var groupByParams = new List<WScalarExpression>(); for (var index = 1; index < node.SelectElements.Count; ++index) { var element = node.SelectElements[index] as WSelectScalarExpression; if (element == null) return null; //sink table if (index == 1) { var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression; if (sinkTableColumn == null) return null; var sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value; sinkTable = context[sinkTableName]; sinkNodeIdExpr = new WColumnReferenceExpression(); foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers) sinkNodeIdExpr.Add(identifier); sinkNodeIdExpr.AddIdentifier("GlobalNodeId"); } } var sourceNodeId = new WSelectScalarExpression { SelectExpr = sourceNodeIdExpr, ColumnName = "src", }; var sinkNodeId = new WSelectScalarExpression { SelectExpr = sinkNodeIdExpr, ColumnName = "sink" }; var edgeId = new WSelectScalarExpression { SelectExpr = new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier( new Identifier[] { new Identifier {Value = edgeAlias}, new Identifier {Value = "Edgeid"} } ) }, ColumnName = "edgeid" }; var elements = new List<WSelectElement> { sourceNodeId, sinkNodeId, edgeId }; return new WCommonTableExpression { ExpressionName = new Identifier { Value = tempTableName }, QueryExpression = new WSelectQueryBlock { FromClause = node.FromClause, WhereClause = new WWhereClause { SearchCondition = node.WhereClause.SearchCondition }, HavingClause = node.HavingClause, OrderByClause = node.OrderByClause, TopRowFilter = node.TopRowFilter, UniqueRowFilter = node.UniqueRowFilter, SelectElements = elements, MatchClause = node.MatchClause, } }; }
public virtual void Visit(WColumnReferenceExpression node) { node.AcceptChildren(this); }
internal static WColumnReferenceExpression CreateColumnExpression(string tableName, string columnName) { var columnExpr = new WColumnReferenceExpression { ColumnType = ColumnType.Regular }; if (tableName != null) { var tabIdent = new Identifier { Value = tableName }; columnExpr.Add(tabIdent); } if (columnName == null) return columnExpr; var colIdent = new Identifier { Value = columnName }; columnExpr.Add(colIdent); return columnExpr; }
private WScalarExpression ParseScalarExpression(ScalarExpression scalarExpr) { if (scalarExpr == null) { return null; } switch (scalarExpr.GetType().Name) { case "BinaryExpression": { var bexpr = scalarExpr as BinaryExpression; var wexpr = new WBinaryExpression { ExpressionType = bexpr.BinaryExpressionType, FirstExpr = ParseScalarExpression(bexpr.FirstExpression), SecondExpr = ParseScalarExpression(bexpr.SecondExpression), FirstTokenIndex = bexpr.FirstTokenIndex, LastTokenIndex = bexpr.LastTokenIndex, }; return wexpr; } case "UnaryExpression": { var uexpr = scalarExpr as UnaryExpression; var wuexpr = new WUnaryExpression { Expression = ParseScalarExpression(uexpr.Expression), ExpressionType = uexpr.UnaryExpressionType, FirstTokenIndex = uexpr.FirstTokenIndex, LastTokenIndex = uexpr.LastTokenIndex }; return wuexpr; } case "ColumnReferenceExpression": { var cre = scalarExpr as ColumnReferenceExpression; var wexpr = new WColumnReferenceExpression { MultiPartIdentifier = ParseMultiPartIdentifier(cre.MultiPartIdentifier), ColumnType = cre.ColumnType, FirstTokenIndex = cre.FirstTokenIndex, LastTokenIndex = cre.LastTokenIndex }; return wexpr; } case "ScalarSubquery": { var oquery = scalarExpr as ScalarSubquery; var wexpr = new WScalarSubquery { SubQueryExpr = ParseSelectQueryStatement(oquery.QueryExpression), FirstTokenIndex = oquery.FirstTokenIndex, LastTokenIndex = oquery.LastTokenIndex }; return wexpr; } case "ParenthesisExpression": { var parenExpr = scalarExpr as ParenthesisExpression; var wexpr = new WParenthesisExpression { Expression = ParseScalarExpression(parenExpr.Expression), FirstTokenIndex = parenExpr.FirstTokenIndex, LastTokenIndex = parenExpr.LastTokenIndex, }; return wexpr; } case "FunctionCall": { var fc = scalarExpr as FunctionCall; var wexpr = new WFunctionCall { CallTarget = ParseCallTarget(fc.CallTarget), FunctionName = fc.FunctionName, UniqueRowFilter = fc.UniqueRowFilter, FirstTokenIndex = fc.FirstTokenIndex, LastTokenIndex = fc.LastTokenIndex, }; if (fc.Parameters == null) return wexpr; wexpr.Parameters = new List<WScalarExpression>(fc.Parameters.Count); foreach (var pe in fc.Parameters.Select(ParseScalarExpression).Where(pe => pe != null)) { wexpr.Parameters.Add(pe); } return wexpr; } case "SearchedCaseExpression": { var caseExpr = scalarExpr as SearchedCaseExpression; var wexpr = new WSearchedCaseExpression { FirstTokenIndex = caseExpr.FirstTokenIndex, LastTokenIndex = caseExpr.LastTokenIndex, WhenClauses = new List<WSearchedWhenClause>(caseExpr.WhenClauses.Count) }; foreach (var pwhen in caseExpr.WhenClauses.Select(swhen => new WSearchedWhenClause { WhenExpression = ParseBooleanExpression(swhen.WhenExpression), ThenExpression = ParseScalarExpression(swhen.ThenExpression), FirstTokenIndex = swhen.FirstTokenIndex, LastTokenIndex = swhen.LastTokenIndex, })) { wexpr.WhenClauses.Add(pwhen); } wexpr.ElseExpr = ParseScalarExpression(caseExpr.ElseExpression); return wexpr; } case "CastCall": { var castExpr = scalarExpr as CastCall; var wexpr = new WCastCall { DataType = ParseDataType(castExpr.DataType), Parameter = ParseScalarExpression(castExpr.Parameter), FirstTokenIndex = castExpr.FirstTokenIndex, LastTokenIndex = castExpr.LastTokenIndex, }; return wexpr; } default: { if (!(scalarExpr is ValueExpression)) return null; var wexpr = new WValueExpression { FirstTokenIndex = scalarExpr.FirstTokenIndex, LastTokenIndex = scalarExpr.LastTokenIndex, }; var expr = scalarExpr as Literal; if (expr != null) { wexpr.Value = expr.Value; if (expr.LiteralType == LiteralType.String) { wexpr.SingleQuoted = true; } } else { var reference = scalarExpr as VariableReference; wexpr.Value = reference != null ? reference.Name : ((GlobalVariableExpression)scalarExpr).Name; } return wexpr; } } }
private WSetClause ParseAssignmentSetClause(AssignmentSetClause asSetClause) { var wasSetClause = new WAssignmentSetClause { AssignmentKind = asSetClause.AssignmentKind, FirstTokenIndex = asSetClause.FirstTokenIndex, LastTokenIndex = asSetClause.LastTokenIndex }; if (asSetClause.Column != null) { var wexpr = new WColumnReferenceExpression { MultiPartIdentifier = ParseMultiPartIdentifier(asSetClause.Column.MultiPartIdentifier), ColumnType = asSetClause.Column.ColumnType, FirstTokenIndex = asSetClause.Column.FirstTokenIndex, LastTokenIndex = asSetClause.Column.LastTokenIndex }; wasSetClause.Column = wexpr; } if (asSetClause.NewValue != null) wasSetClause.NewValue = ParseScalarExpression(asSetClause.NewValue); if (asSetClause.Variable != null) wasSetClause.Variable = asSetClause.Variable.Name; return wasSetClause; }
private WMultiCommonTableExpression ConstructDeleteEdgeSelect(WSelectQueryBlock node, WEdgeColumnReferenceExpression edgeCol, string tempTableName ,out WTableReference sinkTable, out WTableReference sourceTable, ref bool hasReversedEdge) { sourceTable = null; sinkTable = null; string sourceTableName = null; string sinkTableName = null; var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression; if (sourceTableScalar == null) return null; var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression; if (sourceTableColumn == null) return null; sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value; var sourceNodeIdExpr = new WColumnReferenceExpression(); foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers) sourceNodeIdExpr.Add(identifier); sourceNodeIdExpr.AddIdentifier("GlobalNodeId"); var collectVarVisitor = new CollectVariableVisitor(); var context = collectVarVisitor.Invoke(node); if (!context.NodeTableDictionary.Any()) { throw new GraphViewException("Missing From Clause in Delete Edge statement"); } WColumnReferenceExpression sinkNodeIdExpr = null; sourceTable = context[sourceTableName]; var groupByParams = new List<WScalarExpression>(); for (var index = 1; index < node.SelectElements.Count; ++index) { var element = node.SelectElements[index] as WSelectScalarExpression; if (element == null) return null; //sink table if (index == 1) { var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression; if (sinkTableColumn == null) return null; sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value; sinkTable = context[sinkTableName]; sinkNodeIdExpr = new WColumnReferenceExpression(); foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers) sinkNodeIdExpr.Add(identifier); sinkNodeIdExpr.AddIdentifier("GlobalNodeId"); } } var sourceNodeId = new WSelectScalarExpression { SelectExpr = sourceNodeIdExpr, ColumnName = "src", }; var sinkNodeId = new WSelectScalarExpression { SelectExpr = sinkNodeIdExpr, ColumnName = "sink" }; var edgeId = new WSelectScalarExpression { SelectExpr = new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier( new Identifier[] { new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)}, new Identifier {Value = "Edgeid"} }) }, ColumnName = "edgeid" }; var sourceTableNameRef = sourceTable as WNamedTableReference; if (sourceTableNameRef == null) throw new GraphViewException("Source table of DELETE EDGE statement should be a named table reference."); var sinkTableNameRef = sinkTable as WNamedTableReference; if (sinkTableNameRef == null) throw new GraphViewException("Sink table of DELETE EDGE statement should be a named table reference."); int compare = string.CompareOrdinal(sourceTableNameRef.TableObjectName.ToString(), sinkTableNameRef.TableObjectName.ToString()); using (var command = Tx.Connection.CreateCommand()) { command.Transaction = Tx; command.Parameters.AddWithValue("@schema", WNamedTableReference.SchemaNameToTuple(sourceTableNameRef.TableObjectName).Item1); command.Parameters.AddWithValue("@tableName", sourceTableNameRef.TableObjectName.Identifiers.Last().Value); command.Parameters.AddWithValue("@colName", edgeCol.MultiPartIdentifier.Identifiers.Last().Value); command.Parameters.AddWithValue("@role", WNodeTableColumnRole.Edge); command.CommandText = string.Format(@" SELECT NodeColumn.HasReversedEdge FROM [{0}] AS NodeColumn WHERE NodeColumn.TableSchema = @schema and NodeColumn.TableName = @tableName and NodeColumn.ColumnName = @colName and NodeColumn.ColumnRole = @role", GraphViewConnection.MetadataTables[1]); using (var reader = command.ExecuteReader()) { if (reader.Read()) { hasReversedEdge = bool.Parse(reader[0].ToString()); } } } var reversedEdgeName = sourceTableNameRef.TableObjectName.Identifiers.Last().Value + "_" + edgeCol.MultiPartIdentifier.Identifiers.Last().Value + "Reversed"; var reversedEdgeId = new WSelectScalarExpression { SelectExpr = new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier( new Identifier[] { new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)}, new Identifier {Value = "Edgeid"} }) }, ColumnName = "edgeid" }; var elements = new List<WSelectElement> { sourceNodeId, sinkNodeId, edgeId }; var reversedElements = new List<WSelectElement> { sourceNodeId, sinkNodeId, reversedEdgeId, }; return new WMultiCommonTableExpression { WCommonTableExpressions = new List<WCommonTableExpression>() { new WCommonTableExpression { ExpressionName = new Identifier { Value = hasReversedEdge && compare == 0 ? tempTableName + "_1" : tempTableName }, QueryExpression = new WSelectQueryBlock { FromClause = node.FromClause, WhereClause = new WWhereClause { SearchCondition = node.WhereClause.SearchCondition }, HavingClause = node.HavingClause, OrderByClause = node.OrderByClause, TopRowFilter = node.TopRowFilter, UniqueRowFilter = node.UniqueRowFilter, SelectElements = elements, MatchClause = node.MatchClause, } }, new WCommonTableExpression { ExpressionName = new Identifier { Value = hasReversedEdge && compare == 0 ? tempTableName + "_2" : tempTableName }, QueryExpression = new WSelectQueryBlock { FromClause = node.FromClause, WhereClause = hasReversedEdge ? new WWhereClause { SearchCondition = ObjectExtensions.Copy(node.WhereClause.SearchCondition), } : node.WhereClause, HavingClause = node.HavingClause, OrderByClause = node.OrderByClause, TopRowFilter = node.TopRowFilter, UniqueRowFilter = node.UniqueRowFilter, SelectElements = hasReversedEdge ? reversedElements : elements, MatchClause = hasReversedEdge? ConstructReversedMatchClause(node, context) : node.MatchClause, } }, } }; }
public virtual void Visit(WColumnReferenceExpression node) { node.AcceptChildren(this); }
internal override ScalarFunction CompileToFunction(QueryCompilationContext context, GraphViewCommand command) { string funcName = FunctionName.ToString().ToLowerInvariant(); switch (funcName) { case "withinarray": WColumnReferenceExpression checkField = Parameters[0] as WColumnReferenceExpression; WColumnReferenceExpression arrayField = Parameters[1] as WColumnReferenceExpression; return(new WithInArray(context.LocateColumnReference(checkField), context.LocateColumnReference(arrayField))); case "withoutarray": checkField = Parameters[0] as WColumnReferenceExpression; arrayField = Parameters[1] as WColumnReferenceExpression; return(new WithOutArray(context.LocateColumnReference(checkField), context.LocateColumnReference(arrayField))); case "hasproperty": checkField = Parameters[0] as WColumnReferenceExpression; WValueExpression propertyName = Parameters[1] as WValueExpression; return(new HasProperty(context.LocateColumnReference(checkField), propertyName.Value)); case "compose1": List <Tuple <string, int> > targetFieldsAndTheirNames = new List <Tuple <string, int> >(); WValueExpression defaultProjectionKey = Parameters[1] as WValueExpression; if (defaultProjectionKey == null) { throw new SyntaxErrorException("The first parameter of Compose1 has to be a WValueExpression."); } for (int i = 0; i < Parameters.Count; i += 2) { WColumnReferenceExpression columnRef = Parameters[i] as WColumnReferenceExpression; WValueExpression name = Parameters[i + 1] as WValueExpression; if (name == null) { throw new SyntaxErrorException("The parameter of Compose1 at an even position has to be a WValueExpression."); } if (columnRef == null) { throw new SyntaxErrorException("The parameter of Compose1 at an odd position has to be a WColumnReference."); } targetFieldsAndTheirNames.Add(new Tuple <string, int>(name.Value, context.LocateColumnReference(columnRef))); } return(new ComposeCompositeField(targetFieldsAndTheirNames, defaultProjectionKey.Value)); case "compose2": List <ScalarFunction> inputOfCompose2 = new List <ScalarFunction>(); foreach (var parameter in Parameters) { inputOfCompose2.Add(parameter.CompileToFunction(context, command)); } return(new Compose2(inputOfCompose2)); case "path": List <Tuple <ScalarFunction, bool, HashSet <string> > > pathStepList; List <ScalarFunction> byFuncList; WPathTableReference.GetPathStepListAndByFuncList(context, command, this.Parameters, out pathStepList, out byFuncList); return(new Path(pathStepList)); default: throw new NotImplementedException("Function " + funcName + " hasn't been implemented."); } throw new NotImplementedException("Function " + funcName + " hasn't been implemented."); }