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; }
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); } }
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); } }
private SparqlGeneratorWhereExpressionTreeVisitor(SparqlQueryBuilder queryBuilder) : base(queryBuilder) { QueryBuilder = queryBuilder; _filterWriter = new FilterWriter(this, queryBuilder, new StringBuilder()); }
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)); }
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)); }
public FilterWriter(SparqlGeneratorWhereExpressionTreeVisitor parentVisitor, SparqlQueryBuilder queryBuilder, StringBuilder filterExpressionBuilder) : base(queryBuilder) { _parent = parentVisitor; _filterExpressionBuilder = filterExpressionBuilder; }