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."); } } }
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); }
internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewCommand command) { // // Parameters: // #1 <WValueExpression>: Vertex label // ... <WPropertyExpression>: The initial properties on vertex // WValueExpression labelValue = (WValueExpression)this.Parameters[0]; Debug.Assert(labelValue.Value != null, "[WAddVTableReference.Compile] Vertex label should not be null"); List <PropertyTuple> vertexProperties = new List <PropertyTuple>(); List <string> projectedField = new List <string>(GraphViewReservedProperties.InitialPopulateNodeProperties); projectedField.Add(GremlinKeyword.Star); projectedField.Add(GremlinKeyword.Label); for (int i = 1; i < this.Parameters.Count; i++) { WPropertyExpression property = (WPropertyExpression)this.Parameters[i]; Debug.Assert(property != null, "[WAddVTableReference.Compile] Vertex property should not be null"); Debug.Assert(property.Cardinality == GremlinKeyword.PropertyCardinality.List, "[WAddVTableReference.Compile] Vertex property should be append-mode"); Debug.Assert(property.Value != null); if (!projectedField.Contains(property.Key.Value)) { projectedField.Add(property.Key.Value); } 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); vertexProperties.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); vertexProperties.Add(valueProperty); } } JObject nodeJsonDocument = ConstructNodeJsonDocument(command, labelValue.Value); AddVOperator addVOp = new AddVOperator( context.CurrentExecutionOperator, command, nodeJsonDocument, projectedField, vertexProperties); context.CurrentExecutionOperator = addVOp; for (int i = 0; i < projectedField.Count; i++) { string propertyName = projectedField[i]; ColumnGraphType columnGraphType = GraphViewReservedProperties.IsNodeReservedProperty(propertyName) ? GraphViewReservedProperties.ReservedNodePropertiesColumnGraphTypes[propertyName] : ColumnGraphType.Value; context.AddField(Alias.Value, propertyName, columnGraphType); } // Convert the connection to Hybrid if necessary if (command.Connection.GraphType != GraphType.GraphAPIOnly) { command.Connection.GraphType = GraphType.Hybrid; } return(addVOp); }
internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewCommand command) { WScalarSubquery srcSubQuery = Parameters[0] as WScalarSubquery; WScalarSubquery sinkSubQuery = Parameters[1] as WScalarSubquery; if (srcSubQuery == null || sinkSubQuery == null) { throw new SyntaxErrorException("The first two parameters of AddE can only be WScalarSubquery."); } Container container = new Container(); QueryCompilationContext srcSubContext = new QueryCompilationContext(context); srcSubContext.OuterContextOp.SetContainer(container); GraphViewExecutionOperator srcSubQueryOp = srcSubQuery.SubQueryExpr.Compile(srcSubContext, command); QueryCompilationContext sinkSubContext = new QueryCompilationContext(context); sinkSubContext.OuterContextOp.SetContainer(container); GraphViewExecutionOperator sinkSubQueryOp = sinkSubQuery.SubQueryExpr.Compile(sinkSubContext, command); WValueExpression otherVTagParameter = Parameters[2] as WValueExpression; Debug.Assert(otherVTagParameter != null, "otherVTagParameter != null"); // // if otherVTag == 0, this newly added edge's otherV() is the src vertex. // Otherwise, it's the sink vertex // int otherVTag = int.Parse(otherVTagParameter.Value); WValueExpression labelValue = (WValueExpression)this.Parameters[3]; List <WPropertyExpression> edgeProperties = new List <WPropertyExpression>(); List <PropertyTuple> subtraversalProperties = new List <PropertyTuple>(); List <string> projectedField = new List <string>(GraphViewReservedProperties.ReservedEdgeProperties); projectedField.Add(GremlinKeyword.Label); for (int i = 4; i < this.Parameters.Count; i++) { WPropertyExpression property = (WPropertyExpression)this.Parameters[i]; Debug.Assert(property != null, "[WAddETableReference.Compile] Edge property should not be null"); Debug.Assert(property.Cardinality == GremlinKeyword.PropertyCardinality.Single, "[WAddETableReference.Compile] Edge property should not be append-mode"); Debug.Assert(property.Value != null); if (!projectedField.Contains(property.Key.Value)) { projectedField.Add(property.Key.Value); } if (property.Value is WValueExpression) { edgeProperties.Add(property); } else { WScalarSubquery scalarSubquery = property.Value as WScalarSubquery; ScalarSubqueryFunction valueFunction = (ScalarSubqueryFunction)scalarSubquery.CompileToFunction(context, command); subtraversalProperties.Add(new PropertyTuple(property.Cardinality, property.Key.Value, valueFunction)); } } JObject edgeJsonObject = ConstructEdgeJsonObject(command, labelValue.Value, edgeProperties); // metadata remains missing GraphViewExecutionOperator addEOp = new AddEOperator(context.CurrentExecutionOperator, command, container, srcSubQueryOp, sinkSubQueryOp, otherVTag, edgeJsonObject, projectedField, subtraversalProperties); context.CurrentExecutionOperator = addEOp; // Update context's record layout context.AddField(Alias.Value, GremlinKeyword.EdgeSourceV, ColumnGraphType.EdgeSource); context.AddField(Alias.Value, GremlinKeyword.EdgeSinkV, ColumnGraphType.EdgeSink); context.AddField(Alias.Value, GremlinKeyword.EdgeOtherV, ColumnGraphType.Value); context.AddField(Alias.Value, GremlinKeyword.EdgeID, ColumnGraphType.EdgeId); context.AddField(Alias.Value, GremlinKeyword.Star, ColumnGraphType.EdgeObject); for (var i = GraphViewReservedProperties.ReservedEdgeProperties.Count; i < projectedField.Count; i++) { context.AddField(Alias.Value, projectedField[i], ColumnGraphType.Value); } return(addEOp); }