A reference to a column. Columns in the SELECT clause are wrapped by the WSelectElement class. This class represents columns as scalar expressions. In particular, when WColumnReferenceExpression is of type *, it appears in function calls such as COUNT(*)
Inheritance: WPrimaryExpression
        public override void Visit(WColumnReferenceExpression node)
        {
            var column = node.MultiPartIdentifier.Identifiers;

            if (column.Count >= 2)
            {
                var tableName    = column.First().Value;
                var propertyName = "";
                HashSet <string> properties;
                if (!_tableandPropertiesDict.TryGetValue(tableName, out properties))
                {
                    _tableandPropertiesDict[tableName] = new HashSet <string>();
                }
                propertyName += column[1].Value;
                for (var i = 2; i < column.Count; i++)
                {
                    propertyName += "." + column[i].ToString();
                }
                _tableandPropertiesDict[tableName].Add(propertyName);
            }
            else
            {
                throw new GraphViewException("Identifier " + column.ToString() + " should be bound to a table.");
            }
        }
        public override void Visit(WColumnReferenceExpression node)
        {
            if (!_referencedByNodeAndEdge)
            {
                return;
            }
            var    column     = node.MultiPartIdentifier.Identifiers;
            string tableAlias = "";

            if (column.Count >= 2)
            {
                tableAlias = column[column.Count - 2].Value;
            }
            else
            {
                var columnName = column.Last().Value;
                if ((_columnTableMapping.ContainsKey(columnName)))
                {
                    tableAlias = _columnTableMapping[columnName];
                }
            }

            if (!_graph.ContainsNode(tableAlias))
            {
                _referencedByNodeAndEdge = false;
            }
        }
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            IList <Identifier> columnList   = columnReference.MultiPartIdentifier.Identifiers;
            string             propertyName = "";

            if (columnList.Count == 2)
            {
                string originalColumnName = columnList[1].Value;

                if (originalColumnName.Equals(GremlinKeyword.NodeID, StringComparison.InvariantCultureIgnoreCase) ||
                    originalColumnName.Equals(GremlinKeyword.Label, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                string encodeName = EncodeString(originalColumnName);
                referencedProperties[encodeName] = originalColumnName;
                columnList[0].Value = encodeName;
                columnList[1].Value = NormalizeWColumnReferenceExpressionVisitor.ReservedPropertyKeyName;
            }
            else
            {
                throw new QueryCompilationException("Identifier " + columnList.ToString() + " should be bound to a table.");
            }
        }
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            IList <Identifier> columnList   = columnReference.MultiPartIdentifier.Identifiers;
            string             propertyName = "";

            if (columnList.Count == 2)
            {
                string tableName = columnList[0].Value;
                if (this.skipTableNames.Contains(tableName))
                {
                    return;
                }

                string originalColumnName = columnList[1].Value;
                if (this.flatProperties.Contains(originalColumnName))
                {
                    return;
                }

                columnReference.AddIdentifier("*");
                columnReference.AddIdentifier("_value");
            }
            else
            {
                throw new QueryCompilationException("Identifier " + columnList + " should be bound to a table.");
            }
        }
Beispiel #5
0
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            IList <Identifier> columnList   = columnReference.MultiPartIdentifier.Identifiers;
            string             propertyName = "";

            if (columnList.Count == 2)
            {
                string originalColumnName = columnList[1].Value;

                if (originalColumnName.Equals(GremlinKeyword.NodeID) ||
                    originalColumnName.Equals(GremlinKeyword.Label))
                {
                    return;
                }

                string encodeName = EncodeString(originalColumnName);
                referencedProperties[encodeName] = originalColumnName;
                columnList[0].Value = encodeName;
                columnList[1].Value = GraphViewKeywords.KW_PROPERTY_VALUE;
            }
            else
            {
                throw new QueryCompilationException("Identifier " + columnList.ToString() + " should be bound to a table.");
            }
        }
 //
 // E_0.|id => E_0['|id']
 //
 public override void Visit(WColumnReferenceExpression node)
 {
     if (this.NeedsConvertion.Count == 0 || this.NeedsConvertion.Contains(node.TableReference))
     {
         node.MultiPartIdentifier = new DMultiPartIdentifier(node.MultiPartIdentifier);
     }
 }
Beispiel #7
0
        internal static WColumnReferenceExpression CreateColumnExpression(string tableName, string columnName)
        {
            var columnExpr = new WColumnReferenceExpression {
                ColumnType = ColumnType.Regular
            };

            if (tableName != null)
            {
                var tabIdent = new Identifier {
                    Value = tableName
                };
                columnExpr.Add(tabIdent);
            }

            if (columnName == null)
            {
                return(columnExpr);
            }

            var colIdent = new Identifier {
                Value = columnName
            };

            columnExpr.Add(colIdent);

            return(columnExpr);
        }
 public override void Visit(WColumnReferenceExpression node)
 {
     if (node.MultiPartIdentifier == null)
         return;
     var column = node.MultiPartIdentifier.Identifiers;
     if (column.Count >= 2)
     {
         var columnName = column[column.Count - 2].Value;
         if (_edgeTableReferenceDict.ContainsKey(columnName))
         {
             if (_edgeTableReferenceDict[columnName].Count > 1)
                 throw new GraphViewException("Ambiguious Table Reference");
             column[column.Count - 2].Value = _edgeTableReferenceDict[columnName].First();
         }
     }
     //else
     //{
     //    var columnName = column.Last().Value;
     //    if (_columnTableDict.ContainsKey(columnName))
     //    {
     //        column.Insert(0, new Identifier { Value = _columnTableDict[columnName] });
     //    }
     //}
     base.Visit(node);
 }
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            IList <Identifier> columnList   = columnReference.MultiPartIdentifier.Identifiers;
            string             propertyName = "";

            if (columnList.Count == 2)
            {
                string tableName = columnList[0].Value;
                if (this.skipTableNames.Contains(tableName))
                {
                    return;
                }

                string originalColumnName = columnList[1].Value;
                if (this.flatProperties.Contains(originalColumnName))
                {
                    return;
                }

                string encodeName = EncodeString(originalColumnName);
                this.referencedProperties[encodeName] = originalColumnName;
                columnList[0].Value = encodeName;
                columnList[1].Value = DocumentDBKeywords.KW_PROPERTY_VALUE;
            }
            else
            {
                throw new QueryCompilationException("Identifier " + columnList + " should be bound to a table.");
            }
        }
Beispiel #10
0
        /// <summary>
        /// Generate the Table-Valued Function by the edge given the node alias
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="nodeAlias"></param>
        /// <returns></returns>
        private static WTableReference EdgeToTableReference(MatchEdge edge, string nodeAlias)
        {
            var edgeColumn      = edge.EdgeColumn;
            var edgeIdentifiers = edge.EdgeColumn.MultiPartIdentifier.Identifiers;

            if (nodeAlias != edgeIdentifiers.First().Value)
            {
                var identifiers = new List <Identifier>(edgeIdentifiers);
                identifiers.RemoveAt(0);
                identifiers.Insert(0, new Identifier
                {
                    Value = nodeAlias
                });
                edgeColumn = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier
                    {
                        Identifiers = identifiers
                    }
                };
            }
            var columnName       = edgeIdentifiers.Last().Value;
            var deColIdentifiers = new Identifier[]
            {
                edgeColumn.MultiPartIdentifier.Identifiers.First(),
                new Identifier {
                    Value = columnName + "DeleteCol"
                }
            };
            var decoderFunction = new Identifier
            {
                Value = edge.SourceNode.TableObjectName.SchemaIdentifier.Value + '_' +
                        edge.SourceNode.TableObjectName.BaseIdentifier.Value + '_' +
                        columnName + '_' +
                        "Decoder",
            };
            var tableRef = new WSchemaObjectFunctionTableReference
            {
                SchemaObject = new WSchemaObjectName(
                    new Identifier {
                    Value = "dbo"
                },
                    decoderFunction),
                Parameters = new List <WScalarExpression>
                {
                    edgeColumn,
                    new WColumnReferenceExpression
                    {
                        MultiPartIdentifier = new WMultiPartIdentifier(deColIdentifiers)
                    }
                },
                Alias = new Identifier
                {
                    Value = edge.EdgeAlias,
                }
            };

            return(tableRef);
        }
 public override void Visit(WColumnReferenceExpression node)
 {
     var columnExpr = node.MultiPartIdentifier.Identifiers;
     if (columnExpr.Count >= 2)
         _tables.Add(columnExpr[columnExpr.Count - 2].Value.ToLower(CultureInfo.CurrentCulture));
     else
         _unboundColumns.Add(columnExpr.Last().Value.ToLower(CultureInfo.CurrentCulture));
 }
        public override void Visit(WColumnReferenceExpression node)
        {
            string nodeStr = node.MultiPartIdentifier != null
                ? node.MultiPartIdentifier.ToString()
                : "";

            this.dfsStack.Push(nodeStr);
        }
        /// <summary>
        /// Adds a new field to the raw records when a new execution operator is added to the execution plan.
        /// </summary>
        /// <param name="tableAlias"></param>
        /// <param name="columnName"></param>
        /// <param name="type"></param>
        public void AddField(string tableAlias, string columnName, ColumnGraphType type)
        {
            int index = RawRecordLayout.Count;
            WColumnReferenceExpression colRef = new WColumnReferenceExpression(tableAlias, columnName);

            colRef.ColumnGraphType  = type;
            RawRecordLayout[colRef] = index;
        }
Beispiel #14
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.");
                }
            }
        }
        public override void Visit(WColumnReferenceExpression node)
        {
            if (_tableExists)
            {
                return;
            }
            if (node.MultiPartIdentifier == null)
            {
                return;
            }
            var columnIdentifiers = node.MultiPartIdentifier.Identifiers;
            var columnName        = columnIdentifiers.Last().Value;

            switch (columnIdentifiers.Count)
            {
            // unbound column, no need to check because all unbounded columns have been bounded to a table when constructing the graph
            case 1:
                if (_columnTableMapping.ContainsKey(columnName) &&
                    String.Equals(_columnTableMapping[columnName], _tableName,
                                  StringComparison.CurrentCultureIgnoreCase))
                {
                    _tableExists = true;
                }
                break;

            // column referencd by exposed name
            case 2:
                var tableExposedName = columnIdentifiers[0].Value;
                if (String.Equals(tableExposedName, _tableName, StringComparison.CurrentCultureIgnoreCase))
                {
                    _tableExists = true;
                }
                break;

            // column referencd by complete table name
            default:
                var flag   = true;
                var index1 = columnIdentifiers.Count - 2;
                var index2 = _tableRef.TableObjectName.Count - 1;
                for (; index1 >= 0 && index2 >= 0; --index1, --index2)
                {
                    if (String.Equals(columnIdentifiers[index1].Value, _tableRef.TableObjectName[index2].Value,
                                      StringComparison.CurrentCultureIgnoreCase))
                    {
                        continue;
                    }
                    flag = false;
                    break;
                }
                _tableExists = flag;
                break;
            }
        }
 /// <summary>
 /// Given a column reference, returns its offset in the raw records produced by the SQL statement.
 /// </summary>
 /// <param name="columnReference"></param>
 /// <returns></returns>
 public int LocateColumnReference(WColumnReferenceExpression columnReference)
 {
     if (RawRecordLayout.ContainsKey(columnReference))
     {
         return(RawRecordLayout[columnReference]);
     }
     else
     {
         throw new QueryCompilationException(string.Format("Column reference {0} cannot be located in the raw records in the current execution pipeline.",
                                                           columnReference.ToString("")));
     }
 }
Beispiel #17
0
        public override void Visit(WColumnReferenceExpression node)
        {
            var columnExpr = node.MultiPartIdentifier.Identifiers;

            if (columnExpr.Count >= 2)
            {
                _tables.Add(columnExpr[columnExpr.Count - 2].Value.ToLower(CultureInfo.CurrentCulture));
            }
            else
            {
                _unboundColumns.Add(columnExpr.Last().Value.ToLower(CultureInfo.CurrentCulture));
            }
        }
        /// <summary>
        /// Given a column reference, i.e., the composite key of (table alias, column name),
        /// return its offset in raw records produced by the SQL statement.
        /// </summary>
        /// <param name="tableAlias">Table alias</param>
        /// <param name="columnName">Column name</param>
        /// <returns>The offset of the column reference in the raw records</returns>
        public int LocateColumnReference(string tableAlias, string columnName)
        {
            WColumnReferenceExpression targetName = new WColumnReferenceExpression(tableAlias, columnName);

            if (RawRecordLayout.ContainsKey(targetName))
            {
                return(RawRecordLayout[targetName]);
            }
            else
            {
                throw new QueryCompilationException(string.Format("Column reference {0}.{1} cannot be located in the raw records in the current execution pipeline.",
                                                                  tableAlias, columnName));
            }
        }
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            var key   = columnReference.TableReference;
            var value = columnReference.ColumnName;

            foreach (var item in map)
            {
                if (item.Key.TableReference.Equals(key) && item.Key.ColumnName.Equals(value))
                {
                    columnReference.MultiPartIdentifier.Identifiers[0].Value = GremlinKeyword.RepeatInitalTableName;
                    columnReference.MultiPartIdentifier.Identifiers[1].Value = item.Value;
                }
            }
        }
Beispiel #20
0
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            string key   = columnReference.TableReference;
            string value = columnReference.ColumnName;

            foreach (KeyValuePair <Tuple <string, string>, Tuple <string, string> > item in this.Map)
            {
                if (item.Key.Item1.Equals(key) && item.Key.Item2.Equals(value))
                {
                    columnReference.MultiPartIdentifier.Identifiers[0].Value = item.Value.Item1;
                    columnReference.MultiPartIdentifier.Identifiers[1].Value = item.Value.Item2;
                }
            }
        }
Beispiel #21
0
        public override void Visit(WColumnReferenceExpression columnReference)
        {
            var key   = columnReference.MultiPartIdentifier.Identifiers[0].Value;
            var value = columnReference.MultiPartIdentifier.Identifiers[1].Value;

            foreach (var item in _map)
            {
                if (item.Key.GremlinVariable.GetVariableName().Equals(key) && item.Key.VariableProperty.Equals(value))
                {
                    columnReference.MultiPartIdentifier.Identifiers[0].Value = "R";
                    columnReference.MultiPartIdentifier.Identifiers[1].Value = item.Value;
                }
            }
        }
 public override void Visit(WColumnReferenceExpression node)
 {
     var column = node.MultiPartIdentifier.Identifiers;
     if (column.Count >= 2)
     {
         Bind(column[column.Count - 2].Value);
     }
     else
     {
         var columnName = column.Last().Value;
         Bind(_columnToTable.ContainsKey(columnName) ?
             _columnToTable[columnName] :
             "");
     }
 }
        public override void Visit(WColumnReferenceExpression node)
        {
            var column = node.MultiPartIdentifier.Identifiers;

            if (column.Count >= 2 && _tableName.Equals(column.First().Value, StringComparison.OrdinalIgnoreCase))
            {
                column.First().Value = _tableName;
            }
            else
            {
                node.MultiPartIdentifier.Identifiers.Insert(0, new Identifier {
                    Value = _tableName
                });
            }
        }
Beispiel #24
0
        internal GraphViewExecutionOperator Compile2(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            WColumnReferenceExpression dropTargetParameter = Parameters[0] as WColumnReferenceExpression;

            Debug.Assert(dropTargetParameter != null, "dropTargetParameter != null");
            int dropTargetIndex = context.LocateColumnReference(dropTargetParameter);

            //
            // A new DropOperator which drops target based on its runtime type
            //
            DropNodeOperator dropOp = new DropNodeOperator(context.CurrentExecutionOperator, dbConnection, dropTargetIndex);

            context.CurrentExecutionOperator = dropOp;

            return(dropOp);
        }
Beispiel #25
0
        public override void Visit(WColumnReferenceExpression node)
        {
            var column = node.MultiPartIdentifier.Identifiers;

            if (column.Count >= 2)
            {
                Bind(column[column.Count - 2].Value);
            }
            else
            {
                var columnName = column.Last().Value;
                Bind(_columnToTable.ContainsKey(columnName) ?
                     _columnToTable[columnName] :
                     "");
            }
        }
Beispiel #26
0
        public override void Visit(WColumnReferenceExpression node)
        {
            string columnName = node.ColumnName;
            string tableAlias = node.TableReference;

            if (tableAlias == null)
            {
                throw new QueryCompilationException("Identifier " + columnName + " must be bound to a table alias.");
            }

            if (accessedColumns.ContainsKey(tableAlias))
            {
                accessedColumns[tableAlias].Add(columnName);
            }
            else
            {
                _isOnlyTargetTableReferenced = false;
            }
        }
Beispiel #27
0
        public override bool Equals(object obj)
        {
            WColumnReferenceExpression colRef = obj as WColumnReferenceExpression;

            if (colRef == null || MultiPartIdentifier.Count != colRef.MultiPartIdentifier.Count)
            {
                return(false);
            }

            for (int i = 0; i < MultiPartIdentifier.Count; i++)
            {
                if (MultiPartIdentifier[i].Value != colRef.MultiPartIdentifier[i].Value)
                {
                    return(false);
                }
            }

            return(true);
        }
 public override void Visit(WColumnReferenceExpression node)
 {
     if (_tableExists)
         return;
     if (node.MultiPartIdentifier == null) return;
     var columnIdentifiers = node.MultiPartIdentifier.Identifiers;
     var columnName = columnIdentifiers.Last().Value;
     switch (columnIdentifiers.Count)
     {
         // unbound column, no need to check because all unbounded columns have been bounded to a table when constructing the graph
         case 1:
             if (_columnTableMapping.ContainsKey(columnName) &&
                 String.Equals(_columnTableMapping[columnName], _tableName,
                     StringComparison.OrdinalIgnoreCase))
                 _tableExists = true;
             break;
         // column referencd by exposed name
         case 2:
             var tableExposedName = columnIdentifiers[0].Value;
             if (String.Equals(tableExposedName, _tableName, StringComparison.OrdinalIgnoreCase))
                 _tableExists = true;
             break;
         // column referencd by complete table name
         default:
             var flag = true;
             var index1 = columnIdentifiers.Count - 2;
             var index2 = _tableRef.TableObjectName.Count - 1;
             for (; index1 >= 0 && index2 >= 0; --index1, --index2)
             {
                 if (String.Equals(columnIdentifiers[index1].Value, _tableRef.TableObjectName[index2].Value,
                     StringComparison.OrdinalIgnoreCase))
                     continue;
                 flag = false;
                 break;
             }
             _tableExists = flag;
             break;
     }
 }
Beispiel #29
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            WColumnReferenceExpression updateParameter = this.Parameters[0] as WColumnReferenceExpression;
            int updateIndex    = context.LocateColumnReference(updateParameter);
            var propertiesList = new List <WPropertyExpression>();

            for (int i = 1; i < this.Parameters.Count; ++i)
            {
                propertiesList.Add((WPropertyExpression)this.Parameters[i]);
#if DEBUG
                ((WPropertyExpression)this.Parameters[i]).Value.ToJValue();
#endif
            }

            UpdatePropertiesOperator updateOp = new UpdatePropertiesOperator(
                context.CurrentExecutionOperator,
                dbConnection,
                updateIndex,
                propertiesList);
            context.CurrentExecutionOperator = updateOp;

            return(updateOp);
        }
Beispiel #30
0
        /// <summary>
        /// Adds a new field to the raw records when a new execution operator is added to the execution plan.
        /// </summary>
        /// <param name="tableAlias"></param>
        /// <param name="columnName"></param>
        /// <param name="type"></param>
        /// <param name="insertAtFront"></param>
        public void AddField(string tableAlias, string columnName, ColumnGraphType type, bool insertAtFront = false)
        {
            WColumnReferenceExpression colRef = new WColumnReferenceExpression(tableAlias, columnName);

            colRef.ColumnGraphType = type;

            if (insertAtFront)
            {
                foreach (WColumnReferenceExpression column in this.RawRecordLayout.Keys.ToList())
                {
                    ++this.RawRecordLayout[column];
                    if (this.ParentContextRawRecordLayout != null && this.ParentContextRawRecordLayout.ContainsKey(column))
                    {
                        ++this.ParentContextRawRecordLayout[column];
                    }
                }
                this.RawRecordLayout[colRef] = 0;
            }
            else
            {
                int index = this.RawRecordLayout.Count;
                this.RawRecordLayout[colRef] = index;
            }
        }
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewCommand command)
        {
            WColumnReferenceExpression updateParameter = this.Parameters[0] as WColumnReferenceExpression;
            int updateIndex = context.LocateColumnReference(updateParameter);
            List <PropertyTuple> propertiesList = new List <PropertyTuple>();

            for (int i = 1; i < this.Parameters.Count; ++i)
            {
                WPropertyExpression property = this.Parameters[i] as WPropertyExpression;
                if (property.Value is WValueExpression)
                {
                    WValueExpression value = property.Value as WValueExpression;
                    Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> > meta = new Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> >();

                    foreach (KeyValuePair <WValueExpression, WScalarExpression> pair in property.MetaProperties)
                    {
                        string name = pair.Key.Value;
                        if (pair.Value is WValueExpression)
                        {
                            WValueExpression metaValue = pair.Value as WValueExpression;
                            meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(metaValue.ToStringField(), null));
                        }
                        else
                        {
                            WScalarSubquery        metaScalarSubquery = pair.Value as WScalarSubquery;
                            ScalarSubqueryFunction metaValueFunction  = (ScalarSubqueryFunction)metaScalarSubquery.CompileToFunction(context, command);
                            meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(null, metaValueFunction));
                        }
                    }

                    PropertyTuple valueProperty = new PropertyTuple(property.Cardinality, property.Key.Value, value.ToStringField(), meta);
                    propertiesList.Add(valueProperty);
                }
                else
                {
                    WScalarSubquery        scalarSubquery = property.Value as WScalarSubquery;
                    ScalarSubqueryFunction valueFunction  = (ScalarSubqueryFunction)scalarSubquery.CompileToFunction(context, command);

                    Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> > meta = new Dictionary <string, Tuple <StringField, ScalarSubqueryFunction> >();
                    foreach (KeyValuePair <WValueExpression, WScalarExpression> pair in property.MetaProperties)
                    {
                        string name = pair.Key.Value;
                        if (pair.Value is WValueExpression)
                        {
                            WValueExpression metaValue = pair.Value as WValueExpression;
                            meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(metaValue.ToStringField(), null));
                        }
                        else
                        {
                            WScalarSubquery        metaScalarSubquery = pair.Value as WScalarSubquery;
                            ScalarSubqueryFunction metaValueFunction  = (ScalarSubqueryFunction)metaScalarSubquery.CompileToFunction(context, command);
                            meta.Add(name, new Tuple <StringField, ScalarSubqueryFunction>(null, metaValueFunction));
                        }
                    }

                    PropertyTuple valueProperty = new PropertyTuple(property.Cardinality, property.Key.Value, valueFunction, meta);
                    propertiesList.Add(valueProperty);
                }
            }

            UpdatePropertiesOperator updateOp = new UpdatePropertiesOperator(
                context.CurrentExecutionOperator,
                command,
                updateIndex,
                propertiesList);

            context.CurrentExecutionOperator = updateOp;

            return(updateOp);
        }
Beispiel #32
0
        /// <summary>
        /// Given a node / TVF, a traversalLink and backwardEdges, try to find all predicates that can be evaluated
        /// </summary>
        /// <param name="node"></param>
        /// <param name="traversalLink"></param>
        /// <param name="backwardEdges"></param>
        /// <param name="predicateLinksAccessedTableAliases"></param>
        private List <Tuple <PredicateLink, int> > FindPredicates(
            CompileNode node,
            CompileLink traversalLink,
            List <Tuple <MatchEdge, int> > backwardEdges,
            List <Tuple <PredicateLink, HashSet <string> > > predicateLinksAccessedTableAliases)
        {
            // Record temporary aliases and predicates
            HashSet <string> temporaryAliases               = new HashSet <string>(this.ExistingNodesAndEdges);
            HashSet <string> temporaryPredicates            = new HashSet <string>(this.ExistingPredicateLinks);
            List <Tuple <PredicateLink, int> > forwardLinks = new List <Tuple <PredicateLink, int> >();

            // priority = 1
            // retrieve traversalLink and add predicates
            if (traversalLink != null && !this.ExistingNodesAndEdges.Contains(traversalLink.LinkAlias))
            {
                // Find predicates that can be evaluated after retrieving this traversalLink
                if (traversalLink is MatchEdge)
                {
                    temporaryAliases.Add(traversalLink.LinkAlias);
                }
                else if (traversalLink is PredicateLink)
                {
                    temporaryPredicates.Add(traversalLink.LinkAlias);
                }
                else
                {
                    throw new QueryCompilationException("Cannot support " + traversalLink + " as a traversal link or an edge");
                }

                foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases)
                {
                    if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) &&
                        temporaryAliases.IsSupersetOf(tuple.Item2))
                    {
                        temporaryPredicates.Add(tuple.Item1.LinkAlias);
                        forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 1));
                    }
                }

                // Make sure the all existing edges and this traversalLink are consistent
                // Because all existing edges are consistent, we just need make one exstring edge and this traversalLink consistent
                MatchNode matchNode = node as MatchNode;
                WColumnReferenceExpression nodeColumnReferenceExprFromTraversalLink  = GetNodeColumnReferenceExprFromLink(traversalLink);
                WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(matchNode, this.ExistingNodesAndEdges);
                if (nodeColumnReferenceExprFromTraversalLink != null &&
                    nodeColumnReferenceExprFromAnExistingEdge != null)
                {
                    forwardLinks.Add(
                        new Tuple <PredicateLink, int>(
                            new PredicateLink(
                                SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromTraversalLink,
                                                                      nodeColumnReferenceExprFromAnExistingEdge)), 1));
                }
            }

            // priority = 2
            // retrieve node and some edges and add predicates
            temporaryAliases.Add(node.NodeAlias);
            foreach (Tuple <MatchEdge, int> tuple in backwardEdges)
            {
                if (tuple.Item2 == 2)
                {
                    temporaryAliases.Add(tuple.Item1.LinkAlias);
                    MatchNode otherNode = tuple.Item1.SinkNode;
                    WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge   = null;
                    WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges);
                    if (nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        foreach (MatchEdge edge in otherNode.Neighbors)
                        {
                            if (edge.LinkAlias == tuple.Item1.LinkAlias)
                            {
                                nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                break;
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.ReverseNeighbors)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.DanglingEdges)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                    }
                    // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent
                    if (nodeColumnReferenceExprFromBackwardEdge != null &&
                        nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        temporaryPredicates.Add(tuple.Item1.LinkAlias);
                        forwardLinks.Add(
                            new Tuple <PredicateLink, int>(
                                new PredicateLink(
                                    SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge,
                                                                          nodeColumnReferenceExprFromAnExistingEdge)), 2));
                    }
                }
            }

            // Check predicates
            foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases)
            {
                if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) &&
                    temporaryAliases.IsSupersetOf(tuple.Item2))
                {
                    temporaryPredicates.Add(tuple.Item1.LinkAlias);
                    forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 2));
                }
            }

            // priority = 3
            // retrieve another edges and add predicates
            foreach (Tuple <MatchEdge, int> tuple in backwardEdges)
            {
                if (tuple.Item2 == 3)
                {
                    temporaryAliases.Add(tuple.Item1.LinkAlias);
                    MatchNode otherNode = tuple.Item1.SinkNode;
                    WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge   = null;
                    WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges);
                    if (nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        foreach (MatchEdge edge in otherNode.Neighbors)
                        {
                            if (edge.LinkAlias == tuple.Item1.LinkAlias)
                            {
                                nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                break;
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.ReverseNeighbors)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.DanglingEdges)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                    }
                    // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent
                    if (nodeColumnReferenceExprFromBackwardEdge != null &&
                        nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        temporaryPredicates.Add(tuple.Item1.LinkAlias);
                        forwardLinks.Add(
                            new Tuple <PredicateLink, int>(
                                new PredicateLink(
                                    SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge,
                                                                          nodeColumnReferenceExprFromAnExistingEdge)), 3));
                    }
                }
            }

            // Check predicates
            foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases)
            {
                if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) &&
                    temporaryAliases.IsSupersetOf(tuple.Item2))
                {
                    temporaryPredicates.Add(tuple.Item1.LinkAlias);
                    forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 3));
                }
            }
            return(forwardLinks);
        }
Beispiel #33
0
        private WBooleanExpression ConstructJoinCondition(
            CandidateJoinUnit candidateTree,
            IMatchJoinStatisticsCalculator statisticsCalculator,
            GraphMetaData metaData,
            Dictionary<Tuple<string, bool>, Statistics> srcNodeStatisticsDict,
            out double preJoinSelectivity,
            out double postJoinSelectivity,
            out double sqlEstimatedJoinSelectivity)
        {
            const double sizeThreshold = 1e8;
            const int loopJoinFactorThreshold = 20;

            preJoinSelectivity = 1.0;
            postJoinSelectivity = 1.0;
            sqlEstimatedJoinSelectivity = 1.0;

            var firstJoin = MaterializedNodeSplitCount.Count == 1;
            MatchNode firstNode = null;
            if (firstJoin)
                firstNode = Nodes.First();
            var root = candidateTree.TreeRoot;

            WBooleanExpression joinCondition = null;
            WBooleanExpression whereCondition = null;
            string nodeName = root.RefAlias;

            if (!Nodes.Contains(root))
                Nodes.Add(root);
            MaterializedNodeSplitCount[root] = 0;

            var inEdges =
                candidateTree.PreMatIncomingEdges.Select(
                    e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Pre, e))
                    .Union(
                        candidateTree.PostMatIncomingEdges.Select(
                            e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Post, e)))
                    .ToList();

            var outEdges =
                candidateTree.PreMatOutgoingEdges.Select(
                    e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Pre, e))
                    .Union(
                        candidateTree.PostMatOutgoingEdges.Select(
                            e => new Tuple<MaterializedOrder, MatchEdge>(MaterializedOrder.Post, e)))
                    .ToList();

            var densityList = new List<double>();
            var inPostCount = 0;
            var outPostCount = 0;

            if (inEdges.Any())
            {
                UnmaterializedNodeMapping.Remove(root);
                //joinSelectivity *= 1.0 / root.TableRowCount;

                Statistics statistics = null;
                Statistics srcNodeStat = null;
                foreach (var t in inEdges)
                {
                    var order = t.Item1;
                    var edge = t.Item2;

                    var globalNodeIdRef = new WColumnReferenceExpression
                    {
                        ColumnType = ColumnType.Regular,
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {Value = nodeName},
                            new Identifier {Value = "GlobalNodeId"}
                            )
                    };

                    var newCondition = new WBooleanComparisonExpression
                    {
                        FirstExpr = new WColumnReferenceExpression
                        {
                            ColumnType = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {Value = edge.EdgeAlias},
                                new Identifier {Value = "Sink"}
                                ),
                        },
                        SecondExpr = order == MaterializedOrder.Post && inPostCount > 0
                            ? new WBinaryExpression
                            {
                                ExpressionType = BinaryExpressionType.Add,
                                FirstExpr = globalNodeIdRef,
                                SecondExpr = new WValueExpression
                                {
                                    SingleQuoted = false,
                                    Value = "0",
                                }
                            }
                            : (WScalarExpression)globalNodeIdRef,
                        ComparisonType = BooleanComparisonType.Equals
                    };
                    EdgeMaterilizedDict[edge] = true;

                    double selectivity;
                    statistics = Statistics.UpdateHistogram(statistics,
                        edge.Statistics, out selectivity);

                    if (order == MaterializedOrder.Pre)
                    {
                        preJoinSelectivity *= selectivity;
                        joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition, newCondition);
                    }
                    else
                    {
                        ++inPostCount;
                        postJoinSelectivity *= selectivity;
                        whereCondition = WBooleanBinaryExpression.Conjunction(whereCondition, newCondition);
                    }

                    if (firstJoin)
                    {
                        double srcNodeSelectivity;
                        srcNodeStat = Statistics.UpdateHistogram(srcNodeStat,
                            srcNodeStatisticsDict[new Tuple<string, bool>(edge.EdgeAlias, edge.IsReversedEdge)],
                            out srcNodeSelectivity);
                    }

                    densityList.Add(root.GlobalNodeIdDensity);
                }

                if (firstJoin)
                    SinkNodeStatisticsDict[firstNode] = srcNodeStat;
                SinkNodeStatisticsDict[root] = statistics;
            }

            if (candidateTree.JoinHint == JoinHint.Loop)
            {
                var size = Cardinality*candidateTree.PreMatIncomingEdges.Select(e => e.AverageDegree)
                    .Aggregate(1.0, (cur, next) => cur*next)*preJoinSelectivity;
                if (size >= sizeThreshold && size > root.EstimatedRows * loopJoinFactorThreshold)
                    candidateTree.JoinHint = JoinHint.Hash;
            }

            if (outEdges.Any())
            {
                foreach (var t in outEdges)
                {
                    var order = t.Item1;
                    var edge = t.Item2;
                    var sinkNode = edge.SinkNode;

                    var globalNodeIdRef = new WColumnReferenceExpression
                    {
                        ColumnType = ColumnType.Regular,
                        MultiPartIdentifier = new WMultiPartIdentifier(
                            new Identifier {Value = sinkNode.RefAlias},
                            new Identifier {Value = "GlobalNodeId"}
                            )
                    };

                    var newCondition = new WBooleanComparisonExpression
                    {
                        FirstExpr = new WColumnReferenceExpression
                        {
                            ColumnType = ColumnType.Regular,
                            MultiPartIdentifier = new WMultiPartIdentifier(
                                new Identifier {Value = edge.EdgeAlias},
                                new Identifier {Value = "Sink"}
                                ),
                        },
                        SecondExpr = order == MaterializedOrder.Post && outPostCount > 0
                            ? new WBinaryExpression
                            {
                                ExpressionType = BinaryExpressionType.Add,
                                FirstExpr = globalNodeIdRef,
                                SecondExpr = new WValueExpression
                                {
                                    SingleQuoted = false,
                                    Value = "0",
                                }
                            }
                            : (WScalarExpression)globalNodeIdRef,
                        ComparisonType = BooleanComparisonType.Equals
                    };
                    EdgeMaterilizedDict[edge] = true;

                    Statistics sinkNodeStatistics;
                    if (!SinkNodeStatisticsDict.TryGetValue(sinkNode, out sinkNodeStatistics))
                    {
                        sinkNodeStatistics = null;
                        //joinSelectivity *= 1.0 / sinkNode.TableRowCount;
                    }
                    double selectivity;
                    var statistics = Statistics.UpdateHistogram(sinkNodeStatistics,
                        edge.Statistics, out selectivity);

                    if (order == MaterializedOrder.Pre)
                    {
                        preJoinSelectivity *= selectivity;
                        joinCondition = WBooleanBinaryExpression.Conjunction(joinCondition, newCondition);
                    }
                    else
                    {
                        ++outPostCount;
                        postJoinSelectivity *= selectivity;
                        whereCondition = WBooleanBinaryExpression.Conjunction(whereCondition, newCondition);
                    }

                    SinkNodeStatisticsDict[sinkNode] = statistics;
                    densityList.Add(sinkNode.GlobalNodeIdDensity);
                }
            }

            var unmatEdges = candidateTree.UnmaterializedEdges;
            foreach (var unmatEdge in unmatEdges)
            {
                EdgeMaterilizedDict[unmatEdge] = false;;
                var unmatNodeInEdges = UnmaterializedNodeMapping.GetOrCreate(unmatEdge.SinkNode);
                unmatNodeInEdges.Add(unmatEdge);
            }

            densityList.Sort();
            for (int i = densityList.Count - 1; i >= 0; i--)
            {
                sqlEstimatedJoinSelectivity *= Math.Sqrt(sqlEstimatedJoinSelectivity) * densityList[i];
            }

            WhereCondition = WBooleanBinaryExpression.Conjunction(WhereCondition, whereCondition);

            return joinCondition;
        }
Beispiel #34
0
        /// <summary>
        /// Generate the Table-Valued Function by the edge given the node alias
        /// </summary>
        /// <param name="edge"></param>
        /// <param name="nodeAlias"></param>
        /// <returns></returns>
        private static WTableReference EdgeToTableReference(MatchEdge edge, string nodeAlias)
        {
            var edgeColumn = edge.EdgeColumn;
            var edgeIdentifiers = edge.EdgeColumn.MultiPartIdentifier.Identifiers;
            if (nodeAlias != edgeIdentifiers.First().Value)
            {
                var identifiers = new List<Identifier>(edgeIdentifiers);
                identifiers.RemoveAt(0);
                identifiers.Insert(0, new Identifier
                {
                    Value = nodeAlias
                });
                edgeColumn = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier
                    {
                        Identifiers = identifiers
                    }
                };
                
            }
            var columnName = edgeIdentifiers.Last().Value;
            var deColIdentifiers = new Identifier[]
            {
                edgeColumn.MultiPartIdentifier.Identifiers.First(),
                new Identifier {Value = columnName + "DeleteCol"}
            };
            var decoderFunction = new Identifier
            {
                Value = edge.SourceNode.TableObjectName.SchemaIdentifier.Value + '_' +
                        edge.SourceNode.TableObjectName.BaseIdentifier.Value + '_' + 
                        columnName + '_' +
                        "Decoder",

            };
            var tableRef = new WSchemaObjectFunctionTableReference
            {
                SchemaObject = new WSchemaObjectName(
                    new Identifier {Value = "dbo"},
                    decoderFunction),
                Parameters = new List<WScalarExpression>
                {
                    edgeColumn,
                    new WColumnReferenceExpression
                    {
                        MultiPartIdentifier = new WMultiPartIdentifier(deColIdentifiers)
                    }
                },
                Alias = new Identifier
                {
                    Value = edge.EdgeAlias,
                }
            };
            return tableRef;
        }
        public override void Visit(WColumnReferenceExpression node)
        {
            if (!_referencedByNodeAndEdge) 
                return;
            var column = node.MultiPartIdentifier.Identifiers;
            string tableAlias = "";
            if (column.Count >= 2)
            {
                tableAlias = column[column.Count - 2].Value;
            }
            else
            {
                var columnName = column.Last().Value;
                if ((_columnTableMapping.ContainsKey(columnName)))
                {
                    tableAlias = _columnTableMapping[columnName];
                }
            }

            if (!_graph.ContainsNode(tableAlias))
            {
                _referencedByNodeAndEdge = false;
            }
        }
 public override void Visit(WColumnReferenceExpression node)
 {
     if (node.MultiPartIdentifier == null)
     {
         return;
     }
     var column = node.MultiPartIdentifier.Identifiers;
     var number = column.Count;
     if (number >= 3)
     {
         var tableName = column[number - 2];
         var columName = column[number - 1];
         column.Clear();
         column.Insert(0, tableName);
         column.Insert(1, columName);
     }
 }
        public override void Visit(WSelectQueryBlock node)
        {
            if (node.SelectElements == null || node.SelectElements.Count < 2)
            {
                throw new GraphViewException("Numbers of select elements mismatch.");
            }
            var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression;
            if (sourceTableScalar == null)
                throw new GraphViewException("Source node id should be a scalar expression.");
            var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression;
            if (sourceTableColumn == null)
                throw new GraphViewException("Source node id column should be a column reference expression.");
            var sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value;

            var sourceNodeIdExpr = new WColumnReferenceExpression();
            foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers)
                sourceNodeIdExpr.Add(identifier);
            sourceNodeIdExpr.AddIdentifier("GlobalNodeId");

            if (node.SelectElements.Count < 2)
                throw new GraphViewException("Source and Sink tables should be specified in select elements.");

            if (node.GroupByClause != null)
            {
                throw new GraphViewException("GROUP BY clause is not allowed in INSERT EDGE statement.");
            }
            var collectVarVisitor = new CollectVariableVisitor();
            var context = collectVarVisitor.Invoke(node);
            WColumnReferenceExpression sinkNodeIdExpr = null;

            for (var index = 1; index < node.SelectElements.Count; ++index)
            {
                var element = node.SelectElements[index] as WSelectScalarExpression;
                if (element == null)
                    throw new GraphViewException("Edge property should be a scalar expression.");
                //sink table
                if (index == 1)
                {
                    var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression;
                    if (sinkTableColumn == null)
                        throw new GraphViewException("Sink node id column should be a column reference expression.");

                    var sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value;
                    _sinkTable = context[sinkTableName];

                    sinkNodeIdExpr = new WColumnReferenceExpression();
                    foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers)
                        sinkNodeIdExpr.Add(identifier);
                    sinkNodeIdExpr.AddIdentifier("GlobalNodeId");
                }
                else
                {
                    _edgeProperties.Add(element.SelectExpr);
                }

            }

            var sourceTable = context[sourceTableName] as WNamedTableReference;

            if (sourceTable == null)
            {
                throw new GraphViewException("Source table of INSERT EDGE statement should be a named table reference.");
            }


            var sourceNodeId = new WSelectScalarExpression
            {
                SelectExpr = sourceNodeIdExpr,
                ColumnName = "src",
            };
            var sinkNodeId = new WSelectScalarExpression
            {
                SelectExpr = sinkNodeIdExpr,
                ColumnName = "sink"
            };


            var elements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId
            };

            var result = new WCommonTableExpression
            {
                ExpressionName = new Identifier {Value = _tempTableName},
                QueryExpression = new WSelectQueryBlock
                {
                    FromClause = node.FromClause,
                    WhereClause = new WWhereClause
                    {
                        SearchCondition = node.WhereClause.SearchCondition
                    },
                    HavingClause = node.HavingClause,
                    OrderByClause = node.OrderByClause,
                    TopRowFilter = node.TopRowFilter,
                    UniqueRowFilter = node.UniqueRowFilter,
                    SelectElements = elements,
                    MatchClause = node.MatchClause
                }
            };
            

            _result = result;
        }
        private WCommonTableExpression ConstructDeleteEdgeSelect(WSelectQueryBlock node, string edgeAlias, string tempTableName
            ,out WTableReference sinkTable, out WTableReference sourceTable)
        {
            sourceTable = null;
            sinkTable = null;
            var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression;
            if (sourceTableScalar == null)
                return null;
            var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression;
            if (sourceTableColumn == null)
                return null;
            var sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value;

            var sourceNodeIdExpr = new WColumnReferenceExpression();
            foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers)
                sourceNodeIdExpr.Add(identifier);
            sourceNodeIdExpr.AddIdentifier("GlobalNodeId");

            var collectVarVisitor = new CollectVariableVisitor();
            var context = collectVarVisitor.Invoke(node);
            if (!context.NodeTableDictionary.Any())
            {
                throw new GraphViewException("Missing From Clause in Delete Edge statement");
            }
            WColumnReferenceExpression sinkNodeIdExpr = null;
            sourceTable = context[sourceTableName];

            var groupByParams = new List<WScalarExpression>();
            for (var index = 1; index < node.SelectElements.Count; ++index)
            {
                var element = node.SelectElements[index] as WSelectScalarExpression;
                if (element == null)
                    return null;
                //sink table
                if (index == 1)
                {
                    var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression;
                    if (sinkTableColumn == null)
                        return null;

                    var sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value;
                    sinkTable = context[sinkTableName];

                    sinkNodeIdExpr = new WColumnReferenceExpression();
                    foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers)
                        sinkNodeIdExpr.Add(identifier);
                    sinkNodeIdExpr.AddIdentifier("GlobalNodeId");
                }
            }

            var sourceNodeId = new WSelectScalarExpression
            {
                SelectExpr = sourceNodeIdExpr,
                ColumnName = "src",
            };
            var sinkNodeId = new WSelectScalarExpression
            {
                SelectExpr = sinkNodeIdExpr,
                ColumnName = "sink"
            };
            var edgeId = new WSelectScalarExpression
            {
                SelectExpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier(
                        new Identifier[]
                        {
                            new Identifier {Value = edgeAlias},
                            new Identifier {Value = "Edgeid"}
                        }
                        )
                },
                ColumnName = "edgeid"
            };

            var elements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId,
                edgeId
            };

            return new WCommonTableExpression
            {
                ExpressionName = new Identifier { Value = tempTableName },
                QueryExpression = new WSelectQueryBlock
                {
                    FromClause = node.FromClause,
                    WhereClause = new WWhereClause
                    {
                        SearchCondition = node.WhereClause.SearchCondition
                    },
                    HavingClause = node.HavingClause,
                    OrderByClause = node.OrderByClause,
                    TopRowFilter = node.TopRowFilter,
                    UniqueRowFilter = node.UniqueRowFilter,
                    SelectElements = elements,
                    MatchClause = node.MatchClause,
                }

            };
        }
 public virtual void Visit(WColumnReferenceExpression node)
 {
     node.AcceptChildren(this);
 }
Beispiel #40
0
        internal static WColumnReferenceExpression CreateColumnExpression(string tableName, string columnName)
        {
            var columnExpr = new WColumnReferenceExpression { ColumnType = ColumnType.Regular };

            if (tableName != null)
            {
                var tabIdent = new Identifier { Value = tableName };
                columnExpr.Add(tabIdent);
            }

            if (columnName == null) return columnExpr;

            var colIdent = new Identifier { Value = columnName };
            columnExpr.Add(colIdent);

            return columnExpr;
        }
Beispiel #41
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;
                    }
            }
        }
Beispiel #42
0
        private WSetClause ParseAssignmentSetClause(AssignmentSetClause asSetClause)
        {
            var wasSetClause = new WAssignmentSetClause
            {
                AssignmentKind = asSetClause.AssignmentKind,
                FirstTokenIndex = asSetClause.FirstTokenIndex,
                LastTokenIndex = asSetClause.LastTokenIndex
            };

            if (asSetClause.Column != null)
            {
                var wexpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = ParseMultiPartIdentifier(asSetClause.Column.MultiPartIdentifier),
                    ColumnType = asSetClause.Column.ColumnType,
                    FirstTokenIndex = asSetClause.Column.FirstTokenIndex,
                    LastTokenIndex = asSetClause.Column.LastTokenIndex
                };
                wasSetClause.Column = wexpr;
            }

            if (asSetClause.NewValue != null)
                wasSetClause.NewValue = ParseScalarExpression(asSetClause.NewValue);
            if (asSetClause.Variable != null)
                wasSetClause.Variable = asSetClause.Variable.Name;

            return wasSetClause;
        }
        private WMultiCommonTableExpression ConstructDeleteEdgeSelect(WSelectQueryBlock node, WEdgeColumnReferenceExpression edgeCol, string tempTableName
            ,out WTableReference sinkTable, out WTableReference sourceTable, ref bool hasReversedEdge)
        {
            sourceTable = null;
            sinkTable = null;
            string sourceTableName = null;
            string sinkTableName = null;
            var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression;
            if (sourceTableScalar == null)
                return null;
            var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression;
            if (sourceTableColumn == null)
                return null;
            sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value;

            var sourceNodeIdExpr = new WColumnReferenceExpression();
            foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers)
                sourceNodeIdExpr.Add(identifier);
            sourceNodeIdExpr.AddIdentifier("GlobalNodeId");

            var collectVarVisitor = new CollectVariableVisitor();
            var context = collectVarVisitor.Invoke(node);
            if (!context.NodeTableDictionary.Any())
            {
                throw new GraphViewException("Missing From Clause in Delete Edge statement");
            }
            WColumnReferenceExpression sinkNodeIdExpr = null;
            sourceTable = context[sourceTableName];

            var groupByParams = new List<WScalarExpression>();
            for (var index = 1; index < node.SelectElements.Count; ++index)
            {
                var element = node.SelectElements[index] as WSelectScalarExpression;
                if (element == null)
                    return null;
                //sink table
                if (index == 1)
                {
                    var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression;
                    if (sinkTableColumn == null)
                        return null;

                    sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value;
                    sinkTable = context[sinkTableName];

                    sinkNodeIdExpr = new WColumnReferenceExpression();
                    foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers)
                        sinkNodeIdExpr.Add(identifier);
                    sinkNodeIdExpr.AddIdentifier("GlobalNodeId");
                }
            }

            var sourceNodeId = new WSelectScalarExpression
            {
                SelectExpr = sourceNodeIdExpr,
                ColumnName = "src",
            };
            var sinkNodeId = new WSelectScalarExpression
            {
                SelectExpr = sinkNodeIdExpr,
                ColumnName = "sink"
            };
            var edgeId = new WSelectScalarExpression
            {
                SelectExpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier(
                        new Identifier[]
                        {
                            new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)},
                            new Identifier {Value = "Edgeid"}
                        })
                },
                ColumnName = "edgeid"
            };

            var sourceTableNameRef = sourceTable as WNamedTableReference;
            if (sourceTableNameRef == null)
                throw new GraphViewException("Source table of DELETE EDGE statement should be a named table reference.");
            var sinkTableNameRef = sinkTable as WNamedTableReference;
            if (sinkTableNameRef == null)
                throw new GraphViewException("Sink table of DELETE EDGE statement should be a named table reference.");
            int compare = string.CompareOrdinal(sourceTableNameRef.TableObjectName.ToString(), sinkTableNameRef.TableObjectName.ToString());

            using (var command = Tx.Connection.CreateCommand())
            {
                command.Transaction = Tx;
                command.Parameters.AddWithValue("@schema", WNamedTableReference.SchemaNameToTuple(sourceTableNameRef.TableObjectName).Item1);
                command.Parameters.AddWithValue("@tableName", sourceTableNameRef.TableObjectName.Identifiers.Last().Value);
                command.Parameters.AddWithValue("@colName", edgeCol.MultiPartIdentifier.Identifiers.Last().Value);
                command.Parameters.AddWithValue("@role", WNodeTableColumnRole.Edge);
                command.CommandText = string.Format(@"
                    SELECT NodeColumn.HasReversedEdge
                    FROM [{0}] AS NodeColumn
                    WHERE NodeColumn.TableSchema = @schema and
                          NodeColumn.TableName = @tableName and
                          NodeColumn.ColumnName = @colName and
                          NodeColumn.ColumnRole = @role",
                    GraphViewConnection.MetadataTables[1]);
                using (var reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        hasReversedEdge = bool.Parse(reader[0].ToString());
                    }
                }
            }

            var reversedEdgeName = sourceTableNameRef.TableObjectName.Identifiers.Last().Value +
                                    "_" + edgeCol.MultiPartIdentifier.Identifiers.Last().Value + "Reversed";
            var reversedEdgeId = new WSelectScalarExpression
            {
                SelectExpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier(
                        new Identifier[]
                        {
                            new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)},
                            new Identifier {Value = "Edgeid"}
                        })
                },
                ColumnName = "edgeid"
            };

            var elements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId,
                edgeId
            };

            var reversedElements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId,
                reversedEdgeId,
            };

            return new WMultiCommonTableExpression
            {
                WCommonTableExpressions = new List<WCommonTableExpression>()
                {
                    new WCommonTableExpression
                    {
                        ExpressionName = new Identifier
                        {
                            Value = hasReversedEdge && compare == 0 ? tempTableName + "_1" : tempTableName
                        },
                        QueryExpression = new WSelectQueryBlock
                        {
                            FromClause = node.FromClause,
                            WhereClause = new WWhereClause
                            {
                                SearchCondition = node.WhereClause.SearchCondition
                            },
                            HavingClause = node.HavingClause,
                            OrderByClause = node.OrderByClause,
                            TopRowFilter = node.TopRowFilter,
                            UniqueRowFilter = node.UniqueRowFilter,
                            SelectElements = elements,
                            MatchClause = node.MatchClause,
                        }
                    },
                    new WCommonTableExpression
                    {
                        ExpressionName = new Identifier
                        {
                            Value = hasReversedEdge && compare == 0 ? tempTableName + "_2" : tempTableName
                        },
                        QueryExpression = new WSelectQueryBlock
                        {
                            FromClause = node.FromClause,
                            WhereClause = hasReversedEdge ?
                                new WWhereClause { SearchCondition = ObjectExtensions.Copy(node.WhereClause.SearchCondition), }
                                : node.WhereClause,
                            HavingClause = node.HavingClause,
                            OrderByClause = node.OrderByClause,
                            TopRowFilter = node.TopRowFilter,
                            UniqueRowFilter = node.UniqueRowFilter,
                            SelectElements = hasReversedEdge ? reversedElements : elements,
                            MatchClause = hasReversedEdge? ConstructReversedMatchClause(node, context) : node.MatchClause,
                        }
                    },
                }
            };
        }
 public virtual void Visit(WColumnReferenceExpression node)
 {
     node.AcceptChildren(this);
 }
Beispiel #45
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.");
        }