A value expression can be a variable or a literal.
Inheritance: WPrimaryExpression
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewCommand command)
        {
            var dropTargetParameter = Parameters[0] as WColumnReferenceExpression;
            var dropTargetIndex     = context.LocateColumnReference(dropTargetParameter);

            List <string> populateColumns = new List <string>()
            {
                GremlinKeyword.TableDefaultColumnName
            };

            for (int i = 1; i < this.Parameters.Count; i++)
            {
                WValueExpression populateColumn = this.Parameters[i] as WValueExpression;
                Debug.Assert(populateColumn != null, "populateColumn != null");
                populateColumns.Add(populateColumn.Value);
            }

            var dropOp = new DropOperator(context.CurrentExecutionOperator, command, dropTargetIndex);

            context.CurrentExecutionOperator = dropOp;
            foreach (string columnName in populateColumns)
            {
                context.AddField(Alias.Value, columnName, ColumnGraphType.Value);
            }

            return(dropOp);
        }
示例#2
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            WScalarSubquery srcSubQuery  = this.Parameters[0] as WScalarSubquery;
            WScalarSubquery sinkSubQuery = this.Parameters[1] as WScalarSubquery;

            if (srcSubQuery == null || sinkSubQuery == null)
            {
                throw new SyntaxErrorException("The first two parameters of AddE can only be WScalarSubquery.");
            }
            WValueExpression otherVTagParameter = this.Parameters[2] as WValueExpression;
            WValueExpression edgeLabel          = this.Parameters[3] 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);

            List <WPropertyExpression> edgeProperties = new List <WPropertyExpression>();
            List <string> projectedField = new List <string>();

            for (int i = 4; i < this.Parameters.Count; i += 1)
            {
                WPropertyExpression addedProperty = this.Parameters[i] as WPropertyExpression;
                if (addedProperty != null)
                {
                    edgeProperties.Add(addedProperty);
                }

                WValueExpression projectedProperty = this.Parameters[i] as WValueExpression;
                if (projectedProperty != null)
                {
                    projectedField.Add(projectedProperty.Value);
                }
            }
            JObject edgeJsonObject = this.ConstructEdgeJsonObject(edgeLabel, edgeProperties);

            QueryCompilationContext    srcSubContext = new QueryCompilationContext(context);
            GraphViewExecutionOperator srcSubQueryOp = srcSubQuery.SubQueryExpr.Compile(srcSubContext, dbConnection);

            QueryCompilationContext    sinkSubContext = new QueryCompilationContext(context);
            GraphViewExecutionOperator sinkSubQueryOp = sinkSubQuery.SubQueryExpr.Compile(sinkSubContext, dbConnection);

            GraphViewExecutionOperator addEOp = new AddEOperator(context.CurrentExecutionOperator, dbConnection,
                                                                 srcSubContext.OuterContextOp, srcSubQueryOp, sinkSubContext.OuterContextOp, sinkSubQueryOp,
                                                                 otherVTag, edgeJsonObject, projectedField);

            context.CurrentExecutionOperator = addEOp;

            foreach (string propertyName in projectedField)
            {
                ColumnGraphType columnGraphType = GraphViewReservedProperties.IsEdgeReservedProperty(propertyName)
                    ? GraphViewReservedProperties.ReservedEdgePropertiesColumnGraphTypes[propertyName]
                    : ColumnGraphType.Value;
                context.AddField(this.Alias.Value, propertyName, columnGraphType);
            }

            return(addEOp);
        }
        public static JValue ToJValue(this WValueExpression expr)
        {
            //
            // Special treat when fieldValue indicates null (that is, to remove a property)
            // NOTE: fieldValue itself != null
            //
            if (!expr.SingleQuoted && expr.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }

            //
            // JSON requires a lower case string if it is a boolean value
            //
            bool boolValue;

            if (!expr.SingleQuoted && bool.TryParse(expr.Value, out boolValue))
            {
                return((JValue)boolValue);
            }
            else if (expr.SingleQuoted)
            {
                return((JValue)expr.Value);  // String value
            }
            else
            {
                return((JValue)JToken.Parse(expr.ToString()));
            }
        }
示例#4
0
        public static JProperty UpdateProperty(JObject jsonObject, WValueExpression fieldName, WValueExpression fieldValue)
        {
            string key = fieldName.Value;

            //
            // Special treat when fieldValue indicates null (that is, to remove a property)
            // NOTE: fieldValue itself != null
            //
            if (!fieldValue.SingleQuoted && fieldValue.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                jsonObject.Property(key)?.Remove();
                return(null);
            }

            //
            // JSON requires a lower case string if it is a boolean value
            //
            bool boolValue;

            if (!fieldValue.SingleQuoted && bool.TryParse(fieldValue.Value, out boolValue))
            {
                jsonObject[key] = (JToken)boolValue;
            }
            else
            {
                jsonObject[key] = JToken.Parse(fieldValue.ToString());
            }
            return(jsonObject.Property(key));
        }
示例#5
0
        public override void Visit(WValueExpression valueExpression)
        {
            bool bool_value;

            // JSON requires a lower case string if it is a boolean value
            if (!valueExpression.SingleQuoted && bool.TryParse(valueExpression.Value, out bool_value))
            {
                valueExpression.Value = bool_value.ToString().ToLowerInvariant();
            }
        }
示例#6
0
        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.");
                }
            }
        }
示例#7
0
        public override void Visit(WValueExpression node)
        {
            string value = node.ToString("");

            // TODO: double check, how to use boolean type in database?
//            if (value == "true" || value == "false")
//            {
//                value = $"'{value}'";
//            }
            this.dfsStack.Push(value);
        }
示例#8
0
        public JObject ConstructNodeJsonDocument(string vertexLabel, List <WPropertyExpression> vertexProperties, out List <string> projectedFieldList)
        {
            Debug.Assert(vertexLabel != null);
            JObject vertexObject = new JObject {
                ["label"] = vertexLabel
            };

            projectedFieldList = new List <string>(GraphViewReservedProperties.ReservedNodeProperties);

            foreach (WPropertyExpression vertexProperty in vertexProperties)
            {
                Debug.Assert(vertexProperty.Cardinality == GremlinKeyword.PropertyCardinality.list);

                if (!projectedFieldList.Contains(vertexProperty.Key.Value))
                {
                    projectedFieldList.Add(vertexProperty.Key.Value);
                }

                if (vertexProperty.Value.ToJValue() == null)
                {
                    continue;
                }

                JObject meta = new JObject();
                foreach (KeyValuePair <WValueExpression, WValueExpression> pair in vertexProperty.MetaProperties)
                {
                    WValueExpression metaName  = pair.Key;
                    WValueExpression metaValue = pair.Value;
                    meta[metaName.Value] = metaValue.ToJValue();
                }

                string name      = vertexProperty.Key.Value;
                JArray propArray = (JArray)vertexObject[name];
                if (propArray == null)
                {
                    propArray          = new JArray();
                    vertexObject[name] = propArray;
                }

                propArray.Add(new JObject {
                    ["_value"]  = vertexProperty.Value.ToJValue(),
                    ["_propId"] = GraphViewConnection.GenerateDocumentId(),
                    ["_meta"]   = meta,
                });
                //GraphViewJsonCommand.AppendVertexSinglePropertyToVertex(vertexObject);
            }

            vertexObject["_edge"]           = new JArray();
            vertexObject["_reverse_edge"]   = new JArray();
            vertexObject["_nextEdgeOffset"] = 0;

            return(vertexObject);
        }
示例#9
0
        public JObject ConstructNodeJsonDocument(string vertexLabel, List <WPropertyExpression> vertexProperties)
        {
            Debug.Assert(vertexLabel != null);
            JObject vertexObject = new JObject {
                [KW_VERTEX_LABEL] = vertexLabel
            };

            //projectedFieldList = new List<string>(GraphViewReservedProperties.InitialPopulateNodeProperties);
            //projectedFieldList.Add(GremlinKeyword.Label);

            foreach (WPropertyExpression vertexProperty in vertexProperties)
            {
                Debug.Assert(vertexProperty.Cardinality == GremlinKeyword.PropertyCardinality.List);

                //if (!projectedFieldList.Contains(vertexProperty.Key.Value))
                //    projectedFieldList.Add(vertexProperty.Key.Value);

                //if (vertexProperty.Value.ToJValue() == null) {
                //    continue;
                //}

                JObject meta = new JObject();
                foreach (KeyValuePair <WValueExpression, WValueExpression> pair in vertexProperty.MetaProperties)
                {
                    WValueExpression metaName  = pair.Key;
                    WValueExpression metaValue = pair.Value;
                    meta[metaName.Value] = metaValue.ToJValue();
                }

                string name      = vertexProperty.Key.Value;
                JArray propArray = (JArray)vertexObject[name];
                if (propArray == null)
                {
                    propArray          = new JArray();
                    vertexObject[name] = propArray;
                }

                propArray.Add(new JObject {
                    [KW_PROPERTY_VALUE] = vertexProperty.Value.ToJValue(),
                    [KW_PROPERTY_ID]    = GraphViewConnection.GenerateDocumentId(),
                    [KW_PROPERTY_META]  = meta,
                });
                //GraphViewJsonCommand.AppendVertexSinglePropertyToVertex(vertexObject);
            }

            vertexObject[KW_VERTEX_EDGE]            = new JArray();
            vertexObject[KW_VERTEX_REV_EDGE]        = new JArray();
            vertexObject[KW_VERTEX_EDGE_SPILLED]    = false;
            vertexObject[KW_VERTEX_REVEDGE_SPILLED] = false;
            //vertexObject[KW_VERTEX_NEXTOFFSET] = 0;

            return(vertexObject);
        }
示例#10
0
        public JObject ConstructEdgeJsonObject(WValueExpression edgeLabel, List <WPropertyExpression> addedProperties)
        {
            JObject edgeJsonDocument = new JObject();

            GraphViewJsonCommand.UpdateProperty(edgeJsonDocument, SqlUtil.GetValueExpr(GremlinKeyword.Label), edgeLabel);

            foreach (WPropertyExpression property in addedProperties)
            {
                GraphViewJsonCommand.UpdateProperty(edgeJsonDocument, property.Key, property.Value);
            }

            return(edgeJsonDocument);
        }
示例#11
0
        private void UpdateNodeProperties(
            Dictionary <string, JObject> documentsMap,
            string vertexId,
            JObject vertexDocObject,
            List <Tuple <WValueExpression, WValueExpression, int> > propList,
            UpdatePropertyMode mode)
        {
            VertexField vertexField = this.Connection.VertexCache.GetVertexField(vertexId);

            // Drop all non-reserved properties
            if (propList.Count == 1 &&
                !propList[0].Item1.SingleQuoted &&
                propList[0].Item1.Value.Equals("*", StringComparison.OrdinalIgnoreCase) &&
                !propList[0].Item2.SingleQuoted &&
                propList[0].Item2.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                List <string> toBeDroppedPropertiesNames = GraphViewJsonCommand.DropAllNodeProperties(vertexDocObject);
                foreach (var propertyName in toBeDroppedPropertiesNames)
                {
                    vertexField.VertexProperties.Remove(propertyName);
                }
            }
            else
            {
                foreach (var t in propList)
                {
                    WValueExpression keyExpression   = t.Item1;
                    WValueExpression valueExpression = t.Item2;

                    if (mode == UpdatePropertyMode.Set)
                    {
                        JProperty updatedProperty = GraphViewJsonCommand.UpdateProperty(vertexDocObject, keyExpression, valueExpression);
                        if (updatedProperty == null)
                        {
                            vertexField.VertexProperties.Remove(keyExpression.Value);
                        }
                        else
                        {
                            vertexField.UpdateVertexProperty(updatedProperty.Name, updatedProperty.Value.ToString(),
                                                             JsonDataTypeHelper.GetJsonDataType(updatedProperty.Value.Type));
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            documentsMap[vertexId] = vertexDocObject;
        }
示例#12
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            //
            // Parameters:
            //   #1 <WValueExpression>: Vertex label
            //   ... <WPropertyExpression>: The initial properties on vertex
            //   ... <WValueExpression>: The projected field of AddV

            WValueExpression labelValue = (WValueExpression)this.Parameters[0];

            List <WPropertyExpression> vertexProperties = new List <WPropertyExpression>();
            List <string> projectedField = new List <string>();

            for (int i = 1; i < this.Parameters.Count; i++)
            {
                WPropertyExpression addedProperty = this.Parameters[i] as WPropertyExpression;
                if (addedProperty != null)
                {
                    vertexProperties.Add(addedProperty);
                }

                WValueExpression projectedProperty = this.Parameters[i] as WValueExpression;
                if (projectedProperty != null)
                {
                    projectedField.Add(projectedProperty.Value);
                }
                //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);
            }

            JObject nodeJsonDocument = this.ConstructNodeJsonDocument(labelValue.Value, vertexProperties);

            AddVOperator addVOp = new AddVOperator(
                context.CurrentExecutionOperator,
                dbConnection,
                nodeJsonDocument,
                projectedField);

            context.CurrentExecutionOperator = addVOp;

            foreach (string propertyName in projectedField)
            {
                ColumnGraphType columnGraphType = GraphViewReservedProperties.IsNodeReservedProperty(propertyName)
                    ? GraphViewReservedProperties.ReservedNodePropertiesColumnGraphTypes[propertyName]
                    : ColumnGraphType.Value;
                context.AddField(this.Alias.Value, propertyName, columnGraphType);
            }

            return(addVOp);
        }
示例#13
0
        /// <summary>
        /// </summary>
        /// <param name="command"></param>
        /// <param name="edgeLabel"></param>
        /// <param name="edgeProperties">All propertyValue is WValueExpression!</param>
        /// <returns></returns>
        public JObject ConstructEdgeJsonObject(GraphViewCommand command, string edgeLabel, List <WPropertyExpression> edgeProperties)
        {
            JObject edgeObject = new JObject
            {
                [KW_EDGE_LABEL] = edgeLabel
            };

            // Skip edgeSourceScalarFunction, edgeSinkScalarFunction, otherVTag
            foreach (WPropertyExpression edgeProperty in edgeProperties)
            {
                WValueExpression propertyValue = edgeProperty.Value as WValueExpression;
                GraphViewJsonCommand.UpdateProperty(edgeObject, edgeProperty.Key, propertyValue);
            }

            return(edgeObject);
        }
示例#14
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            //
            // Parameters:
            //   #1 <WValueExpression>: Vertex label
            //   ... <WPropertyExpression>: The initial properties on vertex
            //

            WValueExpression labelValue = (WValueExpression)this.Parameters[0];

            List <WPropertyExpression> vertexProperties = new List <WPropertyExpression>();

            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);

                vertexProperties.Add(property);
            }

            List <string> projectedField;

            JObject nodeJsonDocument = ConstructNodeJsonDocument(labelValue.Value, vertexProperties, out projectedField);

            AddVOperator addVOp = new AddVOperator(
                context.CurrentExecutionOperator,
                dbConnection,
                nodeJsonDocument,
                projectedField);

            context.CurrentExecutionOperator = addVOp;

            context.AddField(Alias.Value, "id", ColumnGraphType.VertexId);
            context.AddField(Alias.Value, "label", ColumnGraphType.Value);
            context.AddField(Alias.Value, "_edge", ColumnGraphType.OutAdjacencyList);
            context.AddField(Alias.Value, "_reverse_edge", ColumnGraphType.InAdjacencyList);
            context.AddField(Alias.Value, "*", ColumnGraphType.VertexObject);
            for (var i = GraphViewReservedProperties.ReservedNodeProperties.Count; i < projectedField.Count; i++)
            {
                context.AddField(Alias.Value, projectedField[i], ColumnGraphType.Value);
            }

            return(addVOp);
        }
示例#15
0
        public static JValue ToJValue(this WValueExpression expr)
        {
            //
            // JSON requires a lower case string if it is a boolean value
            //
            bool boolValue;

            if (!expr.SingleQuoted && bool.TryParse(expr.Value, out boolValue))
            {
                return((JValue)boolValue);
            }
            else if (expr.SingleQuoted)
            {
                return((JValue)expr.Value);  // String value
            }
            else
            {
                return((JValue)JToken.Parse(expr.ToString()));
            }
        }
示例#16
0
        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;
                    }
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#19
0
        /// <summary>
        /// Creates node table and inserts related metadata.
        /// </summary>
        /// <param name="sqlStr">A CREATE TABLE statement with metadata.</param>
        /// <param name="externalTransaction">An existing SqlTransaction instance under which the create node table will occur.</param>
        /// <returns>Returns true if the statement is successfully executed.</returns>
        public bool CreateNodeTable(string sqlStr, SqlTransaction externalTransaction = null)
        {
            // get syntax tree of CREATE TABLE command
            var parser = new GraphViewParser();
            List<WNodeTableColumn> columns;
            IList<ParseError> errors;
            var script = parser.ParseCreateNodeTableStatement(sqlStr, out columns, out errors) as WSqlScript;
            if (errors.Count > 0)
                throw new SyntaxErrorException(errors);

            if (script == null || script.Batches.Count == 0)
            {
                throw new SyntaxErrorException("Invalid CREATE TABLE statement.");
            }

            var statement = script.Batches[0].Statements[0] as WCreateTableStatement;

            var tableSchema = statement.SchemaObjectName.SchemaIdentifier != null
                ? statement.SchemaObjectName.SchemaIdentifier.Value
                : "dbo";
            var tableName = statement.SchemaObjectName.BaseIdentifier.Value;

            SqlTransaction tx;
            if (externalTransaction == null)
            {
                tx = Conn.BeginTransaction();
            }
            else
            {
                tx = externalTransaction;
            }
            // Persists the node table's meta-data
            try
            {
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}] ([TableSchema], [TableName])
                    OUTPUT [Inserted].[TableId]
                    VALUES (@tableSchema, @tableName)", MetadataTables[0]);
                    command.Parameters.AddWithValue("@tableSchema", tableSchema);
                    command.Parameters.AddWithValue("@tableName", tableName);

                    // get generated TableId
                    WValueExpression tableIdentitySeed;
                    using (var reader = command.ExecuteReader())
                    {

                        if (!reader.Read())
                        {
                            return false;
                        }
                        var tableId = Convert.ToInt64(reader["TableId"], CultureInfo.CurrentCulture) << 48;
                        tableIdentitySeed = new WValueExpression(tableId.ToString(CultureInfo.InvariantCulture), false);
                    }

                    // create graph table
                    var wColumnDefinition = statement.Definition.ColumnDefinitions
                        .FirstOrDefault(x => x.ColumnIdentifier.Value == "GlobalNodeId");
                    if (wColumnDefinition != null)
                        wColumnDefinition.IdentityOptions.IdentitySeed = tableIdentitySeed;
                    command.CommandText = statement.ToString();
                    command.ExecuteNonQuery();
                }

                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    // insert graph column
                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}]
                    ([TableSchema], [TableName], [ColumnName], [ColumnRole], [Reference])
                    VALUES (@tableSchema, @tableName, @columnName, @columnRole, @ref)", MetadataTables[1]);

                    command.Parameters.AddWithValue("@tableSchema", tableSchema);
                    command.Parameters.AddWithValue("@tableName", tableName);

                    command.Parameters.Add("@columnName", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@columnRole", SqlDbType.Int);
                    command.Parameters.Add("@ref", SqlDbType.NVarChar, 128);

                    //command.Parameters["@columnName"].Value = "NodeId";
                    //command.Parameters["@columnRole"].Value = (int) WGraphTableColumnRole.NodeId;
                    //command.Parameters["@ref"].Value = SqlChars.Null;
                    //command.ExecuteNonQuery();


                    foreach (var column in columns)
                    {
                        command.Parameters["@columnName"].Value = column.ColumnName.Value;
                        command.Parameters["@columnRole"].Value = (int) column.ColumnRole;
                        var edgeColumn = column as WGraphTableEdgeColumn;
                        if (edgeColumn != null)
                        {
                            command.Parameters["@ref"].Value =
                                (edgeColumn.TableReference as WNamedTableReference).ExposedName.Value;
                        }
                        else
                        {
                            command.Parameters["@ref"].Value = SqlChars.Null;
                        }

                        command.ExecuteNonQuery();
                    }

                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}]
                    ([TableSchema], [TableName], [ColumnName], [AverageDegree])
                    VALUES (@tableSchema, @tableName, @columnName, @AverageDegree)", MetadataTables[3]);
                    command.Parameters.Add("@AverageDegree", SqlDbType.Int);
                    command.Parameters["@AverageDegree"].Value = 5;
                    foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
                    {
                        command.Parameters["@columnName"].Value = column.ColumnName.Value;
                        command.ExecuteNonQuery();
                    }
                }

                // insert graph edge attributes
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}]
                    ([TableSchema], [TableName], [ColumnName], [AttributeName], [AttributeType], [AttributeEdgeId])
                    VALUES (@tableSchema, @tableName, @columnName, @attrName, @attrType, @attrId)", MetadataTables[2]);
                    command.Parameters.AddWithValue("@tableSchema", tableSchema);
                    command.Parameters.AddWithValue("@tableName", tableName);

                    command.Parameters.Add("@columnName", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@attrName", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@attrType", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@attrId", SqlDbType.Int);

                    var createOrder = 1;
                    foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
                    {
                        command.Parameters["@columnName"].Value = column.ColumnName.Value;
                        foreach (var attr in column.Attributes)
                        {
                            command.Parameters["@attrName"].Value = attr.Item1.Value;
                            command.Parameters["@attrType"].Value = attr.Item2.ToString();
                            command.Parameters["@attrId"].Value = (createOrder++).ToString();
                            command.ExecuteNonQuery();
                        }
                    }
                }

                // create column edge sampling table
//            using (var command = new SqlCommand(null, Conn))
//            {
//                    command.Transaction = tx;
//                foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
//                {
//                    command.CommandText = String.Format(CultureInfo.CurrentCulture, @"
//                        CREATE TABLE [{0}_{1}_{2}_Sampling] (
//                            [src] [bigint],
//                            [dst] [bigint]
//                        )", tableSchema, tableName, column.ColumnName.Value);
//                    command.ExecuteNonQuery();
//                }
//            }
                // process edge's Decoder function
                //var edgeDict = columns.OfType<WGraphTableEdgeColumn>()
                //    .ToDictionary(col => col.ColumnName.Value,
                //        col =>
                //            col.Attributes.Select(
                //                x =>
                //                    new Tuple<string, string>(x.Item1.Value,
                //                        x.Item2.ToString().ToLower(CultureInfo.CurrentCulture)))
                //                .ToList());
                var edgeDict =
                    columns.OfType<WGraphTableEdgeColumn>()
                        .Select(
                            col =>
                                new Tuple<string, bool, List<Tuple<string, string>>>(col.ColumnName.Value,
                                    String.Equals(tableName,
                                        (col.TableReference as WNamedTableReference).ExposedName.Value,
                                        StringComparison.CurrentCultureIgnoreCase),
                                    col.Attributes.Select(
                                        x =>
                                            new Tuple<string, string>(x.Item1.Value,
                                                x.Item2.ToString().ToLower(CultureInfo.CurrentCulture)))
                                        .ToList())).ToList();
                if (edgeDict.Count > 0)
                {
                    var assemblyName = tableSchema + '_' + tableName;
                    GraphViewDefinedFunctionGenerator.NodeTableRegister(assemblyName, tableName, edgeDict, Conn, tx);
                }
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
                    {
                        command.CommandText = String.Format(CultureInfo.CurrentCulture, @"
                            SELECT * INTO [{0}_{1}_{2}_Sampling] FROM (
                            SELECT ([GlobalNodeID]+0) as [Src], [Edge].*
                            FROM [{0}].[{1}] WITH (NOLOCK)
                            CROSS APPLY {0}_{1}_{2}_Decoder([{2}],[{2}DeleteCol]) AS Edge
                            WHERE 1=0) as EdgeSample",
                            tableSchema, tableName, column.ColumnName.Value);
                        command.ExecuteNonQuery();
                    }
                }
                if (externalTransaction == null)
                {
                    tx.Commit();
                }
                return true;
            }
            catch (SqlException e)
            {
                if (externalTransaction == null)
                {
                    tx.Rollback();
                }
                throw new SqlExecutionException("An error occurred when creating the node table.", e);
            }
        }
示例#20
0
 public virtual void Visit(WValueExpression node)
 {
     node.AcceptChildren(this);
 }
示例#21
0
 public virtual void Visit(WValueExpression node)
 {
     node.AcceptChildren(this);
 }
示例#22
0
 public override void Visit(WValueExpression node)
 {
     this.dfsStack.Push(node.ToString(""));
 }
示例#23
0
        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);
        }
示例#24
0
 private bool IsOptionNone(WValueExpression option)
 {
     return(!option.SingleQuoted && option.Value.Equals("null", StringComparison.OrdinalIgnoreCase));
 }
示例#25
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,
                }
            });
        }
        internal override RawRecord DataModify(RawRecord record)
        {
            long   edgeOffset  = long.Parse(record[this._edgeOffsetIndex].ToValue);
            string srcVertexId = record[this._srcVertexIdIndex].ToValue;

            JObject srcVertexObject = this.Connection.RetrieveDocumentById(srcVertexId);
            string  outEdgeDocId;
            JObject outEdgeObject;

            EdgeDocumentHelper.FindEdgeBySourceAndOffset(
                this.Connection, srcVertexObject, srcVertexId, edgeOffset, false,
                out outEdgeObject, out outEdgeDocId);
            if (outEdgeObject == null)
            {
                // TODO: Is there something wrong?
                Debug.WriteLine($"[UpdateEdgePropertiesOperator] The edge does not exist: vertexId = {srcVertexId}, edgeOffset = {edgeOffset}");
                return(null);
            }

            string  sinkVertexId = (string)outEdgeObject["_sinkV"];
            JObject sinkVertexObject;
            string  inEdgeDocId;
            JObject inEdgeObject;

            if (sinkVertexId.Equals(srcVertexId))
            {
                sinkVertexObject = srcVertexObject;  // NOTE: Must not use DeepClone() here!
            }
            else
            {
                sinkVertexObject = this.Connection.RetrieveDocumentById(sinkVertexId);
            }
            EdgeDocumentHelper.FindEdgeBySourceAndOffset(
                this.Connection, sinkVertexObject, srcVertexId, edgeOffset, true,
                out inEdgeObject, out inEdgeDocId);

            VertexField srcVertexField  = this.Connection.VertexCache.GetVertexField(srcVertexId);
            VertexField sinkVertexField = this.Connection.VertexCache.GetVertexField(sinkVertexId);
            EdgeField   outEdgeField    = srcVertexField.AdjacencyList.GetEdgeField(srcVertexId, edgeOffset);
            EdgeField   inEdgeField     = sinkVertexField.RevAdjacencyList.GetEdgeField(srcVertexId, edgeOffset);

            // Drop all non-reserved properties
            if (this.PropertiesToBeUpdated.Count == 1 &&
                !this.PropertiesToBeUpdated[0].Item1.SingleQuoted &&
                this.PropertiesToBeUpdated[0].Item1.Value.Equals("*", StringComparison.OrdinalIgnoreCase) &&
                !this.PropertiesToBeUpdated[0].Item2.SingleQuoted &&
                this.PropertiesToBeUpdated[0].Item2.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                List <string> toBeDroppedProperties = GraphViewJsonCommand.DropAllEdgeProperties(outEdgeObject);
                foreach (var propertyName in toBeDroppedProperties)
                {
                    outEdgeField.EdgeProperties.Remove(propertyName);
                }

                toBeDroppedProperties = GraphViewJsonCommand.DropAllEdgeProperties(inEdgeObject);
                foreach (var propertyName in toBeDroppedProperties)
                {
                    inEdgeField.EdgeProperties.Remove(propertyName);
                }
            }
            else
            {
                foreach (Tuple <WValueExpression, WValueExpression, int> tuple in this.PropertiesToBeUpdated)
                {
                    WValueExpression keyExpression   = tuple.Item1;
                    WValueExpression valueExpression = tuple.Item2;

                    if (this.Mode == UpdatePropertyMode.Set)
                    {
                        // Modify edgeObject (update the edge property)
                        JProperty updatedProperty = GraphViewJsonCommand.UpdateProperty(outEdgeObject, keyExpression, valueExpression);
                        // Update VertexCache
                        if (updatedProperty == null)
                        {
                            outEdgeField.EdgeProperties.Remove(keyExpression.Value);
                        }
                        else
                        {
                            outEdgeField.UpdateEdgeProperty(updatedProperty, outEdgeField);
                        }

                        // Modify edgeObject (update the edge property)
                        updatedProperty = GraphViewJsonCommand.UpdateProperty(inEdgeObject, keyExpression, valueExpression);
                        // Update VertexCache
                        if (updatedProperty == null)
                        {
                            inEdgeField.EdgeProperties.Remove(keyExpression.Value);
                        }
                        else
                        {
                            inEdgeField.UpdateEdgeProperty(updatedProperty, inEdgeField);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            // Interact with DocDB to update the property
            EdgeDocumentHelper.UpdateEdgeProperty(this.Connection, srcVertexObject, outEdgeDocId, false, outEdgeObject);
            EdgeDocumentHelper.UpdateEdgeProperty(this.Connection, sinkVertexObject, inEdgeDocId, true, inEdgeObject);


            //
            // Drop edge property
            //
            if (this.PropertiesToBeUpdated.Any(t => t.Item2 == null))
            {
                return(null);
            }
            return(record);
        }
示例#27
0
        /// <summary>
        /// Creates a node table in the graph database.
        /// </summary>
        /// <param name="sqlStr">A CREATE TABLE statement with annotations.</param>
        /// <param name="externalTransaction">An existing SqlTransaction instance under which the create node table will occur.</param>
        /// <returns>True, if the statement is successfully executed.</returns>
        public bool CreateNodeTable(string sqlStr, SqlTransaction externalTransaction = null)
        {
            // get syntax tree of CREATE TABLE command
            var parser = new GraphViewParser();
            List<WNodeTableColumn> columns;
            IList<ParseError> errors;
            var script = parser.ParseCreateNodeTableStatement(sqlStr, out columns, out errors) as WSqlScript;
            if (errors.Count > 0)
                throw new SyntaxErrorException(errors);

            if (script == null || script.Batches.Count == 0)
            {
                throw new SyntaxErrorException("Invalid CREATE TABLE statement.");
            }

            var statement = script.Batches[0].Statements[0] as WCreateTableStatement;

            var tableSchema = statement.SchemaObjectName.SchemaIdentifier != null
                ? statement.SchemaObjectName.SchemaIdentifier.Value
                : "dbo";
            var tableName = statement.SchemaObjectName.BaseIdentifier.Value;

            SqlTransaction tx;
            if (externalTransaction == null)
            {
                tx = Conn.BeginTransaction();
            }
            else
            {
                tx = externalTransaction;
            }
            // Persists the node table's meta-data
            try
            {
                Int64 tableId;
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}] ([TableSchema], [TableName])
                    OUTPUT [Inserted].[TableId]
                    VALUES (@tableSchema, @tableName)", MetadataTables[0]);
                    command.Parameters.AddWithValue("@tableSchema", tableSchema);
                    command.Parameters.AddWithValue("@tableName", tableName);

                    // get generated TableId
                    WValueExpression tableIdentitySeed;
                    using (var reader = command.ExecuteReader())
                    {

                        if (!reader.Read())
                        {
                            return false;
                        }
                        tableId = Convert.ToInt64(reader["TableId"], CultureInfo.CurrentCulture);
                        var tableIdSeek = tableId << 48;
                        tableIdentitySeed = new WValueExpression(tableIdSeek.ToString(CultureInfo.InvariantCulture), false);
                    }

                    // create graph table
                    var wColumnDefinition = statement.Definition.ColumnDefinitions
                        .FirstOrDefault(x => x.ColumnIdentifier.Value == "GlobalNodeId");
                    if (wColumnDefinition != null)
                        wColumnDefinition.IdentityOptions.IdentitySeed = tableIdentitySeed;
                    command.CommandText = statement.ToString();
                    command.ExecuteNonQuery();
                }

                var edgeColumnNameToColumnId = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
                var hasReversedEdge = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    // insert graph column
                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}]
                    ([TableSchema], [TableName], [TableId], [ColumnName], [ColumnRole], [Reference], [HasReversedEdge], [EdgeUdfPrefix])
                    OUTPUT [Inserted].[ColumnId]
                    VALUES (@tableSchema, @tableName, @tableid, @columnName, @columnRole, @ref, @hasRevEdge, @udfPrefix)", MetadataTables[1]);

                    command.Parameters.AddWithValue("@tableSchema", tableSchema);
                    command.Parameters.AddWithValue("@tableName", tableName);
                    command.Parameters.AddWithValue("@tableid", tableId);

                    command.Parameters.Add("@columnName", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@columnRole", SqlDbType.Int);
                    command.Parameters.Add("@ref", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@hasRevEdge", SqlDbType.Bit);
                    command.Parameters.Add("@udfPrefix", SqlDbType.NVarChar, 512);

                    foreach (var column in columns)
                    {
                        command.Parameters["@columnName"].Value = column.ColumnName.Value;
                        command.Parameters["@columnRole"].Value = (int) column.ColumnRole;
                        command.Parameters["@hasRevEdge"].Value = column.ColumnRole == WNodeTableColumnRole.Edge ? 1 : 0;

                        var edgeColumn = column as WGraphTableEdgeColumn;
                        if (edgeColumn != null)
                        {
                            command.Parameters["@ref"].Value =
                                (edgeColumn.TableReference as WNamedTableReference).ExposedName.Value;
                            command.Parameters["@udfPrefix"].Value =
                                tableSchema + "_" + tableName + "_" + column.ColumnName.Value;
                        }
                        else
                        {
                            command.Parameters["@ref"].Value = command.Parameters["@udfPrefix"].Value = SqlChars.Null;
                        }

                        using (var reader = command.ExecuteReader())
                        {
                            if (!reader.Read())
                            {
                                return false;
                            }
                            if (column.ColumnRole == WNodeTableColumnRole.Edge)
                            {
                                edgeColumnNameToColumnId[column.ColumnName.Value] = Convert.ToInt64(reader["ColumnId"].ToString(), CultureInfo.CurrentCulture);
                                hasReversedEdge[column.ColumnName.Value] = true;
                            }
                        }
                    }

                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}]
                    ([TableSchema], [TableName], [ColumnName], [ColumnId], [AverageDegree])
                    VALUES (@tableSchema, @tableName, @columnName, @columnid, @AverageDegree)", MetadataTables[3]);
                    command.Parameters.Add("@AverageDegree", SqlDbType.Int);
                    command.Parameters["@AverageDegree"].Value = 5;
                    command.Parameters.Add("@columnid", SqlDbType.Int);

                    foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
                    {
                        command.Parameters["@columnid"].Value = edgeColumnNameToColumnId[column.ColumnName.Value];
                        command.Parameters["@columnName"].Value = column.ColumnName.Value;
                        command.ExecuteNonQuery();
                    }
                }

                // insert graph edge attributes
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    command.CommandText = string.Format(@"
                    INSERT INTO [{0}]
                    ([TableSchema], [TableName], [ColumnName], [ColumnId], [AttributeName], [AttributeType], [AttributeEdgeId])
                    VALUES (@tableSchema, @tableName, @columnName, @columnid, @attrName, @attrType, @attrId)", MetadataTables[2]);
                    command.Parameters.AddWithValue("@tableSchema", tableSchema);
                    command.Parameters.AddWithValue("@tableName", tableName);

                    command.Parameters.Add("@columnName", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@attrName", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@attrType", SqlDbType.NVarChar, 128);
                    command.Parameters.Add("@attrId", SqlDbType.Int);
                    command.Parameters.Add("@columnid", SqlDbType.Int);

                    var createOrder = 1;
                    foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
                    {
                        command.Parameters["@columnName"].Value = column.ColumnName.Value;
                        foreach (var attr in column.Attributes)
                        {
                            command.Parameters["@attrName"].Value = attr.Item1.Value;
                            command.Parameters["@attrType"].Value = attr.Item2.ToString();
                            command.Parameters["@attrId"].Value = (createOrder++).ToString();
                            command.Parameters["@columnid"].Value = edgeColumnNameToColumnId[column.ColumnName.Value];
                            command.ExecuteNonQuery();
                        }
                    }
                }

                // create column edge sampling table
            //            using (var command = new SqlCommand(null, Conn))
            //            {
            //                    command.Transaction = tx;
            //                foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
            //                {
            //                    command.CommandText = String.Format(CultureInfo.CurrentCulture, @"
            //                        CREATE TABLE [{0}_{1}_{2}_Sampling] (
            //                            [src] [bigint],
            //                            [dst] [bigint]
            //                        )", tableSchema, tableName, column.ColumnName.Value);
            //                    command.ExecuteNonQuery();
            //                }
            //            }
                // process edge's Decoder function
                //var edgeDict = columns.OfType<WGraphTableEdgeColumn>()
                //    .ToDictionary(col => col.ColumnName.Value,
                //        col =>
                //            col.Attributes.Select(
                //                x =>
                //                    new Tuple<string, string>(x.Item1.Value,
                //                        x.Item2.ToString().ToLower(CultureInfo.CurrentCulture)))
                //                .ToList());
                var edgeDict =
                    columns.OfType<WGraphTableEdgeColumn>()
                        .Select(
                            col =>
                                new Tuple<string,int, List<Tuple<string, string>>>(col.ColumnName.Value,
                                    (int)edgeColumnNameToColumnId[col.ColumnName.Value],
                                    col.Attributes.Select(
                                        x =>
                                            new Tuple<string, string>(x.Item1.Value,
                                                x.Item2.ToString().ToLower(CultureInfo.CurrentCulture)))
                                        .ToList())).ToList();
                var userIdColumn = columns.Where(e => e.ColumnRole == WNodeTableColumnRole.NodeId).ToList();
                string userId = (userIdColumn.Count == 0) ? "" : userIdColumn[0].ColumnName.Value;
                if (edgeDict.Count > 0)
                {
                    var assemblyName = tableSchema + '_' + tableName;
                    GraphViewDefinedFunctionRegister register = new NodeTableRegister(assemblyName, tableName, edgeDict, userId);
                    register.Register(Conn, tx);
                }
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    foreach (var column in columns.OfType<WGraphTableEdgeColumn>())
                    {
                        command.CommandText = String.Format(CultureInfo.CurrentCulture, @"
                            SELECT * INTO [{0}_{1}_{2}_Sampling] FROM (
                            SELECT ([GlobalNodeID]+0) as [Src], [Edge].*
                            FROM [{0}].[{1}] WITH (NOLOCK)
                            CROSS APPLY {0}_{1}_{2}_Decoder([{2}],[{2}DeleteCol],0) AS Edge
                            WHERE 1=0) as EdgeSample",
                            tableSchema, tableName, column.ColumnName.Value);
                        command.ExecuteNonQuery();
                    }
                }
                //updateGlobalNodeView(tableSchema, tx);

                // check whether adding reversed edges into the current node table column collection are required
                var reversedEdgeCommandText = String.Empty;
                var reversedEdgeSamplingCommandText = String.Empty;
                var reversedMetaCommandTextList = new List<string>();
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    command.CommandText = String.Format(@"
                        SELECT [ColumnId], [TableSchema], [TableName], [ColumnName], [ColumnRole], [Reference], [HasReversedEdge], [EdgeUdfPrefix]
                        FROM [{0}]
                        WHERE [ColumnRole] = 1 AND [Reference] = '{1}'",
                        MetadataTables[1], tableName);

                    var originalColumnIdList = new List<long>();
                    using (var reader = command.ExecuteReader())
                    {
                        var index = 0;
                        while (reader.Read())
                        {
                            if (!bool.Parse(reader["HasReversedEdge"].ToString())) continue;
                            var sourceTableSchema = reader["TableSchema"].ToString();
                            var sourceTableName = reader["TableName"].ToString();
                            var sourceEdgeName = reader["ColumnName"].ToString();
                            var reversedEdgeName = sourceTableName + "_" + sourceEdgeName + "Reversed";
                            var parameters = new string[]
                            {
                                "@tableSchema" + index,
                                "@tableName" + index,
                                "@tableid" + index,
                                "@columnName" + index,
                                "@columnRole" + index,
                                "@ref" + index,
                                "@refTableSchema" + index,
                                "@isRevEdge" + index,
                                "@udfPrefix" + index
                            };

                            // add reversed edge varbinary columns
                            reversedEdgeCommandText += String.Format(@"
                                ALTER TABLE [{0}].[{1}]
                                ADD [{2}] VARBINARY(MAX) NOT NULL DEFAULT 0x,
                                    [{3}] VARBINARY(MAX) NOT NULL DEFAULT 0x,
                                    [{4}] INT NOT NULL DEFAULT 0;
                                ",
                                tableSchema, tableName,
                                reversedEdgeName,
                                reversedEdgeName + "DeleteCol",
                                reversedEdgeName + "OutDegree");

                            // create reversed edge sampling table
                            reversedEdgeSamplingCommandText += String.Format(@"
                                SELECT * INTO [{0}_{1}_{2}_Sampling] FROM (
                                SELECT ([GlobalNodeID]+0) as [Src], [Edge].*
                                FROM [{0}].[{1}] WITH (NOLOCK)
                                CROSS APPLY {3}_{4}_{5}_Decoder([{2}],[{2}DeleteCol],0) AS Edge
                                WHERE 1=0) as EdgeSample
                                ",
                                tableSchema, tableName, reversedEdgeName,
                                sourceTableSchema, sourceTableName, sourceEdgeName);

                            // update meta info about reversed edges
                            reversedMetaCommandTextList.Add(string.Format(@"
                                INSERT INTO [{0}]
                                ([TableSchema], [TableName], [TableId], [ColumnName], [ColumnRole], [Reference], [RefTableSchema], [IsReversedEdge], [EdgeUdfPrefix])
                                OUTPUT [Inserted].[ColumnId]
                                VALUES ({1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9})
                                ",
                                MetadataTables[1],
                                parameters[0], parameters[1], parameters[2],
                                parameters[3], parameters[4], parameters[5],
                                parameters[6], parameters[7], parameters[8]));

                            command.Parameters.AddWithValue(parameters[0], tableSchema);
                            command.Parameters.AddWithValue(parameters[1], tableName);
                            command.Parameters.AddWithValue(parameters[2], tableId);

                            command.Parameters.AddWithValue(parameters[3], reversedEdgeName);
                            command.Parameters.AddWithValue(parameters[4], Convert.ToInt32(reader["ColumnRole"].ToString(), CultureInfo.CurrentCulture));
                            command.Parameters.AddWithValue(parameters[5], sourceTableName);
                            command.Parameters.AddWithValue(parameters[6], sourceTableSchema);
                            command.Parameters.AddWithValue(parameters[7], 1);
                            command.Parameters.AddWithValue(parameters[8], reader["EdgeUdfPrefix"].ToString());

                            originalColumnIdList.Add(Convert.ToInt64(reader["ColumnId"].ToString(), CultureInfo.CurrentCulture));
                            ++index;
                        }
                    }

                    if (String.IsNullOrEmpty(reversedEdgeCommandText) == false)
                    {
                        command.CommandText = reversedEdgeCommandText;
                        command.ExecuteNonQuery();
                        command.CommandText = reversedEdgeSamplingCommandText;
                        command.ExecuteNonQuery();

                        command.CommandText = String.Format(@"
                            SELECT MAX([AttributeEdgeId]) AS maxAttrEdgeId
                            FROM [{0}]
                            WHERE [TableSchema] = '{1}' AND [TableName] = '{2}'",
                            MetadataTables[2], tableSchema, tableName);

                        var createOrder = 1;
                        using (var reader = command.ExecuteReader())
                        {
                            if (reader.Read())
                            {
                                var startOrder = reader["maxAttrEdgeId"].ToString();
                                createOrder = String.IsNullOrEmpty(startOrder) ? 1 : Convert.ToInt32(startOrder, CultureInfo.CurrentCulture) + 1;
                            }
                        }

                        // NodeTableColumnCollection update
                        for (var i = 0; i < reversedMetaCommandTextList.Count; ++i)
                        {
                            command.CommandText = reversedMetaCommandTextList[i];

                            if (command.Parameters.Contains("@tableSchema"))
                            {
                                command.Parameters.RemoveAt("@tableSchema");
                                command.Parameters.RemoveAt("@tableName");
                                command.Parameters.RemoveAt("@columnName");
                                command.Parameters.RemoveAt("@columnid");
                                command.Parameters.RemoveAt("@AverageDegree");
                                if (command.Parameters.Contains("@attrName"))
                                {
                                    command.Parameters.RemoveAt("@attrName");
                                    command.Parameters.RemoveAt("@attrType");
                                    command.Parameters.RemoveAt("@attrId");
                                }
                            }

                            long reversedColumnId = 0;
                            using (var reader = command.ExecuteReader())
                            {
                                if (!reader.Read())
                                {
                                    return false;
                                }
                                if (Convert.ToInt32(command.Parameters["@columnRole"+i].Value, CultureInfo.CurrentCulture) == 1)
                                {
                                    reversedColumnId = Convert.ToInt64(reader["ColumnId"].ToString(), CultureInfo.CurrentCulture);
                                }
                            }

                            // EdgeAverageDegreeCollection update
                            command.Parameters.AddWithValue("@tableSchema", tableSchema);
                            command.Parameters.AddWithValue("@tableName", tableName);
                            command.Parameters.AddWithValue("@columnName", command.Parameters["@columnName" + i].Value.ToString());
                            command.Parameters.Add("@columnid", SqlDbType.Int);
                            command.Parameters["@columnid"].Value = reversedColumnId;
                            command.Parameters.Add("@AverageDegree", SqlDbType.Int);
                            command.Parameters["@AverageDegree"].Value = 5;

                            command.CommandText = string.Format(@"
                                INSERT INTO [{0}]
                                ([TableSchema], [TableName], [ColumnName], [ColumnId], [AverageDegree])
                                VALUES (@tableSchema, @tableName, @columnName, @columnid, @AverageDegree)", MetadataTables[3]);
                            command.ExecuteNonQuery();

                            // get all original attributes
                            var attributes = new List<Tuple<string, string>>();
                            command.CommandText = String.Format(@"
                                SELECT [AttributeName], [AttributeType]
                                FROM [{0}]
                                WHERE [ColumnId] = {1}",
                                MetadataTables[2], originalColumnIdList[i]);

                            using (var reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    attributes.Add(new Tuple<string, string>(
                                        reader["AttributeName"].ToString(), reader["AttributeType"].ToString()));
                                }
                            }

                            if (attributes.Count == 0) continue;

                            // EdgeAttributeCollection update
                            command.Parameters.Add("@attrName", SqlDbType.NVarChar, 128);
                            command.Parameters.Add("@attrType", SqlDbType.NVarChar, 128);
                            command.Parameters.Add("@attrId", SqlDbType.Int);

                            foreach (var attr in attributes)
                            {
                                command.Parameters["@attrName"].Value = attr.Item1;
                                command.Parameters["@attrType"].Value = attr.Item2;
                                command.Parameters["@attrId"].Value = (createOrder++).ToString();

                                command.CommandText = String.Format(@"
                                    INSERT INTO [{0}]
                                    ([TableSchema], [TableName], [ColumnName], [ColumnId], [AttributeName], [AttributeType], [AttributeEdgeId])
                                    VALUES (@tableSchema, @tableName, @columnName, @columnid, @attrName, @attrType, @attrId)", MetadataTables[2]);
                                command.ExecuteNonQuery();
                            }

                        }
                    }
                }

                // check whether adding reverse edges to pointed node tables are required
                using (var command = new SqlCommand(null, Conn))
                {
                    command.Transaction = tx;
                    foreach (var column in columns.Where(x=>hasReversedEdge.ContainsKey(x.ColumnName.Value)))
                    {
                        command.Parameters.Clear();
                        reversedEdgeCommandText = reversedEdgeSamplingCommandText = String.Empty;

                        var edgeColumn = column as WGraphTableEdgeColumn;
                        if (edgeColumn == null) continue;

                        var refTableName =
                            (edgeColumn.TableReference as WNamedTableReference).ExposedName.Value;
                        string refTableSchema = String.Empty, reversedEdgeName = String.Empty;
                        Int64 refTableId = 0;

                        // skip the edge which connects to the node table itself
                        if (refTableName.Equals(tableName)) continue;

                        command.CommandText = String.Format(@"
                            SELECT [TableId], [TableSchema], [TableName]
                            FROM [{0}]
                            WHERE [TableRole] = 0 AND [TableName] = '{1}'",
                            MetadataTables[0], refTableName);

                        using (var reader = command.ExecuteReader())
                        {
                            // if the target node table exists
                            if (reader.Read())
                            {
                                refTableSchema = reader["TableSchema"].ToString();
                                reversedEdgeName = tableName + "_" + column.ColumnName.Value + "Reversed";

                                // add reversed edge varbinary column
                                reversedEdgeCommandText += String.Format(@"
                                    ALTER TABLE [{0}].[{1}]
                                    ADD [{2}] VARBINARY(MAX) NOT NULL DEFAULT 0x,
                                        [{3}] VARBINARY(MAX) NOT NULL DEFAULT 0x,
                                        [{4}] INT NOT NULL DEFAULT 0
                                    ",
                                    refTableSchema, refTableName,
                                    reversedEdgeName,
                                    reversedEdgeName + "DeleteCol",
                                    reversedEdgeName + "OutDegree");

                                // create reversed edge sampling table
                                reversedEdgeSamplingCommandText += String.Format(@"
                                    SELECT * INTO [{0}_{1}_{2}_Sampling] FROM (
                                    SELECT ([GlobalNodeID]+0) as [Src], [Edge].*
                                    FROM [{0}].[{1}] WITH (NOLOCK)
                                    CROSS APPLY {3}_{4}_{5}_Decoder([{2}],[{2}DeleteCol],0) AS Edge
                                    WHERE 1=0) as EdgeSample
                                    ",
                                    refTableSchema, refTableName, reversedEdgeName,
                                    tableSchema, tableName, column.ColumnName.Value);

                                refTableId = Convert.ToInt64(reader["TableId"], CultureInfo.CurrentCulture);
                            }
                        }

                        // update meta info about reversed edge
                        if (String.IsNullOrEmpty(reversedEdgeCommandText) == false)
                        {
                            command.CommandText = reversedEdgeCommandText;
                            command.ExecuteNonQuery();
                            command.CommandText = reversedEdgeSamplingCommandText;
                            command.ExecuteNonQuery();

                            // NodeTableColumnCollection update
                            command.CommandText = string.Format(@"
                                INSERT INTO [{0}]
                                ([TableSchema], [TableName], [TableId], [ColumnName], [ColumnRole], [Reference], [RefTableSchema], [IsReversedEdge], [EdgeUdfPrefix])
                                OUTPUT [Inserted].[ColumnId]
                                VALUES (@tableSchema, @tableName, @tableid, @columnName, @columnRole, @ref, @refTableSchema, @isRevEdge, @udfPrefix)", MetadataTables[1]);

                            command.Parameters.AddWithValue("@tableSchema", refTableSchema);
                            command.Parameters.AddWithValue("@tableName", refTableName);
                            command.Parameters.AddWithValue("@tableid", refTableId);

                            command.Parameters.AddWithValue("@columnName", reversedEdgeName);
                            command.Parameters.AddWithValue("@columnRole", (int)column.ColumnRole);
                            command.Parameters.AddWithValue("@ref", tableName);
                            command.Parameters.AddWithValue("@refTableSchema", tableSchema);
                            command.Parameters.AddWithValue("@isRevEdge", 1);
                            command.Parameters.AddWithValue("@udfPrefix", tableSchema + "_" + tableName + "_" + column.ColumnName.Value);

                            long reversedColumnId = 0;
                            using (var reader = command.ExecuteReader())
                            {
                                if (!reader.Read())
                                {
                                    return false;
                                }
                                if (column.ColumnRole == WNodeTableColumnRole.Edge)
                                {
                                    reversedColumnId = Convert.ToInt64(reader["ColumnId"].ToString(), CultureInfo.CurrentCulture);
                                }
                            }

                            // EdgeAverageDegreeCollection update
                            command.Parameters.Add("@columnid", SqlDbType.Int);
                            command.Parameters["@columnid"].Value = reversedColumnId;
                            command.Parameters.Add("@AverageDegree", SqlDbType.Int);
                            command.Parameters["@AverageDegree"].Value = 5;

                            command.CommandText = string.Format(@"
                                INSERT INTO [{0}]
                                ([TableSchema], [TableName], [ColumnName], [ColumnId], [AverageDegree])
                                VALUES (@tableSchema, @tableName, @columnName, @columnid, @AverageDegree)", MetadataTables[3]);
                            command.ExecuteNonQuery();

                            command.CommandText = String.Format(@"
                                SELECT MAX([AttributeEdgeId]) AS maxAttrEdgeId
                                FROM [{0}]
                                WHERE [TableSchema] = '{1}' AND [TableName] = '{2}'",
                                MetadataTables[2], refTableSchema, refTableName);

                            var createOrder = 1;
                            using (var reader = command.ExecuteReader())
                            {
                                if (reader.Read())
                                {
                                    var startOrder = reader["maxAttrEdgeId"].ToString();
                                    createOrder = String.IsNullOrEmpty(startOrder) ? 1 : Convert.ToInt32(startOrder, CultureInfo.CurrentCulture) + 1;
                                }
                            }

                            // EdgeAttributeCollection update
                            command.Parameters.Add("@attrName", SqlDbType.NVarChar, 128);
                            command.Parameters.Add("@attrType", SqlDbType.NVarChar, 128);
                            command.Parameters.Add("@attrId", SqlDbType.Int);

                            foreach (var attr in edgeColumn.Attributes)
                            {
                                command.Parameters["@attrName"].Value = attr.Item1.Value;
                                command.Parameters["@attrType"].Value = attr.Item2.ToString();
                                command.Parameters["@attrId"].Value = (createOrder++).ToString();

                                command.CommandText = String.Format(@"
                                    INSERT INTO [{0}]
                                    ([TableSchema], [TableName], [ColumnName], [ColumnId], [AttributeName], [AttributeType], [AttributeEdgeId])
                                    VALUES (@tableSchema, @tableName, @columnName, @columnid, @attrName, @attrType, @attrId)", MetadataTables[2]);
                                command.ExecuteNonQuery();
                            }
                        }
                    }
                }

                UpdateGlobalNodeView(tableSchema, tx);

                if (externalTransaction == null)
                {
                    tx.Commit();
                }
                return true;
            }
            catch (SqlException e)
            {
                if (externalTransaction == null)
                {
                    tx.Rollback();
                }
                throw new SqlExecutionException("An error occurred when creating the node table.\n" + e.Message, e);
            }
        }
示例#28
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,
                }
            };
        }
示例#29
0
        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.");
        }