public static bool CanOptimizeFilter(Expression expression, SparqlQueryBuilder queryBuilder)
        {
            var optimisationChecker = new SparqlGeneratorWhereExpressionOptimisationVisitor(queryBuilder);
            var visitResult         = optimisationChecker.VisitExpression(expression);

            return(visitResult is BooleanFlagExpression && ((BooleanFlagExpression)visitResult).Value);
        }
 private SparqlGeneratorWhereExpressionTreeVisitor(SparqlQueryBuilder queryBuilder, bool optimizeFilter, bool isBoolean)
     : base(queryBuilder)
 {
     QueryBuilder         = queryBuilder;
     _filterWriter        = new FilterWriter(this, queryBuilder, new StringBuilder());
     _optimizeFilter      = optimizeFilter;
     _inBooleanExpression = isBoolean;
 }
Example #3
0
        public static void GetSparqlExpression(Expression expression, SparqlQueryBuilder queryBuilder)
        {
            var visitor          = new SparqlGeneratorSelectExpressionTreeVisitor(queryBuilder);
            var resultExpression = visitor.VisitExpression(expression);

            if (resultExpression is SelectVariableNameExpression)
            {
                queryBuilder.AddSelectVariable((resultExpression as SelectVariableNameExpression).Name);
            }
        }
Example #4
0
        public static Expression GetSparqlExpression(Expression expression, SparqlQueryBuilder queryBuilder)
        {
            var visitor            = new SparqlGeneratorWhereExpressionTreeVisitor(queryBuilder);
            var returnedExpression = visitor.VisitExpression(expression);

            if (returnedExpression is SelectVariableNameExpression && expression.Type.Equals(typeof(bool)))
            {
                var svn = (SelectVariableNameExpression)returnedExpression;
                // Single boolean member expression requires a special case addition to the filter
                queryBuilder.AddFilterExpression("(?" + svn.Name + " = true)");
            }
            queryBuilder.AddFilterExpression(visitor.FilterExpression);
            return(returnedExpression);
        }
        public static Expression GetSparqlExpression(Expression expression, SparqlQueryBuilder queryBuilder, bool filterOptimizationEnabled)
        {
            var canOptimizeFilter  = filterOptimizationEnabled && CanOptimizeFilter(expression, queryBuilder);
            var visitor            = new SparqlGeneratorWhereExpressionTreeVisitor(queryBuilder, canOptimizeFilter, expression.Type == typeof(bool));
            var returnedExpression = visitor.VisitExpression(expression);
            var svn = returnedExpression as SelectVariableNameExpression;

            if (svn != null && expression.Type == typeof(bool))
            {
                // Single boolean member expression requires a special case addition to the filter
                queryBuilder.AddFilterExpression("(?" + svn.Name + " = true)");
            }
            queryBuilder.AddFilterExpression(visitor.FilterExpression);
            return(returnedExpression);
        }
        public static void GetSparqlExpression(Expression expression, SparqlQueryBuilder queryBuilder)
        {
            var visitor          = new SparqlGeneratorSelectExpressionTreeVisitor(queryBuilder);
            var resultExpression = visitor.VisitExpression(expression);

            if (resultExpression is SelectIdentifierVariableNameExpression)
            {
                var selectId  = resultExpression as SelectIdentifierVariableNameExpression;
                var selectVar = queryBuilder.NextVariable();
                queryBuilder.AddBindExpression("STRAFTER(STR(?" + selectId.Name + "), " + SparqlQueryBuilder.QuoteLiteralString(selectId.IdentifierPrefix) + ")", selectVar);
                queryBuilder.AddSelectVariable(selectVar);
            }
            else if (resultExpression is SelectVariableNameExpression)
            {
                queryBuilder.AddSelectVariable((resultExpression as SelectVariableNameExpression).Name);
            }
        }
Example #7
0
 private SparqlGeneratorWhereExpressionTreeVisitor(SparqlQueryBuilder queryBuilder) : base(queryBuilder)
 {
     QueryBuilder  = queryBuilder;
     _filterWriter = new FilterWriter(this, queryBuilder, new StringBuilder());
 }
Example #8
0
 public FilterWriter(ExpressionTreeVisitorBase parentVisitor, SparqlQueryBuilder queryBuilder, StringBuilder filterExpressionBuilder) : base(queryBuilder)
 {
     _parent = parentVisitor;
     _filterExpressionBuilder = filterExpressionBuilder;
 }
 SparqlGeneratorQueryModelVisitor(EntityContext context)
 {
     _context = context;
     _queryBuilder  = new SparqlQueryBuilder(context);
 }
 protected ExpressionTreeVisitorBase(SparqlQueryBuilder queryBuilder)
 {
     QueryBuilder = queryBuilder;
 }
 private SparqlGeneratorSelectExpressionTreeVisitor(SparqlQueryBuilder queryBuilder) : base(queryBuilder)
 {
     _queryBuilder = queryBuilder;
 }
 public SparqlGeneratorWhereExpressionOptimisationVisitor(SparqlQueryBuilder queryBuilder)
 {
     _queryBuilder = queryBuilder;
 }
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is ContainsResultOperator)
            {
                var contains = (ContainsResultOperator)expression.QueryModel.ResultOperators[0];
                if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.Constant &&
                    contains.Item is MemberExpression)
                {
                    var memberExpression  = (MemberExpression)contains.Item;
                    var itemExpression    = VisitExpression(contains.Item);
                    var varNameExpression = itemExpression as SelectVariableNameExpression;
                    if (varNameExpression != null)
                    {
                        if (IsIdInArraySubQuery(memberExpression, expression.QueryModel.MainFromClause.FromExpression))
                        {
                            var varName = varNameExpression.Name;
                            // The subquery is a filter on a resource IRI
                            // It is more efficient to use a UNION of BIND triple patterns than a FILTER
                            var values =
                                ((ConstantExpression)expression.QueryModel.MainFromClause.FromExpression).Value as
                                IEnumerable;
                            if (values != null)
                            {
                                var identifierProperty = memberExpression.Member as PropertyInfo;
                                QueryBuilder.StartUnion();
                                foreach (var value in values)
                                {
                                    QueryBuilder.StartUnionElement();
                                    QueryBuilder.AddBindExpression(
                                        "<" + QueryBuilder.Context.MapIdToUri(identifierProperty, value.ToString()) +
                                        ">", varName);
                                    QueryBuilder.EndUnionElement();
                                }
                                QueryBuilder.EndUnion();
                                return(expression);
                            }
                            return(base.VisitSubQueryExpression(expression));
                        }
                        else
                        {
                            // The subquery is a filter on a resource property expression
                            // We can translate the subquery to an IN expression
                            _filterWriter.WriteInFilter(itemExpression,
                                                        expression.QueryModel.MainFromClause.FromExpression);
                            return(expression);
                        }
                    }
                }
                else if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.MemberAccess)
                {
                    var itemExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                    if (itemExpression is SelectVariableNameExpression)
                    {
                        _filterWriter.WriteInFilter(expression.QueryModel.MainFromClause.FromExpression,
                                                    contains.Item);
                        return(expression);
                    }
                }
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AllResultOperator)
            {
                var all            = (AllResultOperator)expression.QueryModel.ResultOperators[0];
                var existingWriter = _filterWriter;
                _filterWriter = new FilterWriter(this, QueryBuilder, new StringBuilder()); // TODO: Could check FromExpression to see if it is optimisable
                QueryBuilder.StartNotExists();
                var mappedExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedExpression);
                _filterWriter.WriteInvertedFilterPredicate(all.Predicate);
                QueryBuilder.AddFilterExpression(_filterWriter.FilterExpression);
                QueryBuilder.EndNotExists();
                _filterWriter = existingWriter;
                return(expression);
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AnyResultOperator)
            {
                QueryBuilder.StartExists();
                var outerFilterWriter = _filterWriter;
                _filterWriter = new FilterWriter(this, QueryBuilder, new StringBuilder());
                var itemVarName = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);

                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name,
                                                itemVarName);
                }

                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                var innerFilter = _filterWriter.ToString();
                if (!string.IsNullOrEmpty(innerFilter))
                {
                    QueryBuilder.AddFilterExpression(innerFilter);
                }
                _filterWriter = outerFilterWriter;
                QueryBuilder.EndExists();
                return(expression);
            }
            else if (expression.QueryModel.ResultOperators.Count == 0)
            {
                var itemVarName          = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);
                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    // Rename the variable in the SPARQL so that it matches the LINQ variable
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name, itemVarName);
                    (mappedFromExpression as SelectVariableNameExpression).Name = itemVarName;
                }
                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                return(mappedFromExpression);
            }
            return(base.VisitSubQueryExpression(expression));
        }
Example #14
0
 public SparqlGeneratorWhereExpressionOptimisationVisitor(SparqlQueryBuilder queryBuilder)
 {
     _queryBuilder = queryBuilder;
 }
Example #15
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is ContainsResultOperator)
            {
                var contains = expression.QueryModel.ResultOperators[0] as ContainsResultOperator;
                if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.Constant &&
                    contains.Item is MemberExpression)
                {
                    var itemExpression = VisitExpression(contains.Item);
                    if (itemExpression is SelectVariableNameExpression)
                    {
                        // We can translate the subquery to an IN expression
                        _filterWriter.WriteInFilter(contains.Item, expression.QueryModel.MainFromClause.FromExpression);
                        return(expression);
                    }
                }
                else if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.MemberAccess)
                {
                    var itemExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                    if (itemExpression is SelectVariableNameExpression)
                    {
                        _filterWriter.WriteInFilter(expression.QueryModel.MainFromClause.FromExpression,
                                                    contains.Item);
                        return(expression);
                    }
                }
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AllResultOperator)
            {
                var all = expression.QueryModel.ResultOperators[0] as AllResultOperator;
                if (all != null)
                {
                    FilterWriter existingWriter = _filterWriter;
                    _filterWriter = new FilterWriter(this, this.QueryBuilder, new StringBuilder());
                    QueryBuilder.StartNotExists();
                    var mappedExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                    QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedExpression);
                    _filterWriter.WriteInvertedFilterPredicate(all.Predicate);
                    QueryBuilder.AddFilterExpression(_filterWriter.FilterExpression);
                    QueryBuilder.EndNotExists();
                    _filterWriter = existingWriter;
                    return(expression);
                }
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AnyResultOperator)
            {
                QueryBuilder.StartExists();
                var outerFilterWriter = _filterWriter;
                _filterWriter = new FilterWriter(this, QueryBuilder, new StringBuilder());
                var itemVarName = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);

                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name,
                                                itemVarName);
                }

                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                var innerFilter = _filterWriter.ToString();
                if (!String.IsNullOrEmpty(innerFilter))
                {
                    QueryBuilder.AddFilterExpression(innerFilter);
                }
                _filterWriter = outerFilterWriter;
                QueryBuilder.EndExists();
                return(expression);
            }
            else if (expression.QueryModel.ResultOperators.Count == 0)
            {
                var itemVarName          = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);
                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    // Rename the variable in the SPARQL so that it matches the LINQ variable
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name, itemVarName);
                    (mappedFromExpression as SelectVariableNameExpression).Name = itemVarName;
                }
                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                return(mappedFromExpression);
            }
            return(base.VisitSubQueryExpression(expression));
        }
Example #16
0
 SparqlGeneratorQueryModelVisitor(EntityContext context)
 {
     _context      = context;
     _queryBuilder = new SparqlQueryBuilder(context);
 }
Example #17
0
 public FilterWriter(SparqlGeneratorWhereExpressionTreeVisitor parentVisitor, SparqlQueryBuilder queryBuilder,
                     StringBuilder filterExpressionBuilder) : base(queryBuilder)
 {
     _parent = parentVisitor;
     _filterExpressionBuilder = filterExpressionBuilder;
 }