public override Expression VisitSqlRoot(SqlRootExpression expression, object context) { if (expression.TableExpressions.Count == 1) { return(expression); } List <TableExpression> reorderedExpressions = expression.TableExpressions.OrderByDescending(t => { if (t.NormalizedPredicate is MissingSearchParameterExpression) { return(-10); } switch (t.SearchParameterQueryGenerator) { case ReferenceSearchParameterQueryGenerator _: return(10); case CompartmentSearchParameterQueryGenerator _: return(10); case IncludeQueryGenerator _: return(-20); default: return(0); } }).ToList(); return(new SqlRootExpression(reorderedExpressions, expression.DenormalizedExpressions)); }
public override Expression VisitSqlRoot(SqlRootExpression expression, SearchOptions context) { if (context.CountOnly) { return(expression); } // Proceed if we sort params were requested. if (context.Sort.Count == 0) { return(expression); } // _lastUpdated sort param is handled differently than others, because it can be // inferred directly from the resource table itself. if (context.Sort[0].searchParameterInfo.Name == KnownQueryParameterNames.LastUpdated) { return(expression); } var queryGenerator = _normalizedSearchParameterQueryGeneratorFactory.GetNormalizedSearchParameterQueryGenerator(context.Sort[0].searchParameterInfo); var newNormalizedPredicates = new List <TableExpression>(expression.TableExpressions.Count + 1); newNormalizedPredicates.AddRange(expression.TableExpressions); newNormalizedPredicates.Add(new TableExpression(queryGenerator, new SortExpression(context.Sort[0].searchParameterInfo), null, TableExpressionKind.Sort)); return(new SqlRootExpression(newNormalizedPredicates, expression.DenormalizedExpressions)); }
public override Expression VisitSqlRoot(SqlRootExpression expression, object context) { if (expression.TableExpressions.Count == 1 || expression.TableExpressions.All(e => e.Kind != TableExpressionKind.Include)) { return(expression); } bool containsInclude = false; List <TableExpression> reorderedExpressions = expression.TableExpressions.OrderByDescending(t => { switch (t.SearchParameterQueryGenerator) { case IncludeQueryGenerator _: containsInclude = true; return(0); default: return(10); } }).ToList(); if (containsInclude) { reorderedExpressions.Add(IncludeUnionAllExpression); } return(new SqlRootExpression(reorderedExpressions, expression.DenormalizedExpressions)); }
public override Expression VisitSqlRoot(SqlRootExpression expression, SearchOptions context) { if (context.CountOnly) { return(expression); } // Proceed if we sort params were requested. if (context.Sort.Count == 0) { return(expression); } // _type and _lastUpdated sort params are handled differently than others, because they can be // inferred directly from the resource table itself. if (context.Sort.All(s => s.searchParameterInfo.Name is SearchParameterNames.ResourceType or SearchParameterNames.LastUpdated)) { return(expression); } var queryGenerator = _searchParamTableExpressionQueryGeneratorFactory.GetSearchParamTableExpressionQueryGenerator(context.Sort[0].searchParameterInfo); var newTableExpressions = new List <SearchParamTableExpression>(expression.SearchParamTableExpressions.Count + 1); newTableExpressions.AddRange(expression.SearchParamTableExpressions); newTableExpressions.Add(new SearchParamTableExpression(queryGenerator, new SortExpression(context.Sort[0].searchParameterInfo), SearchParamTableExpressionKind.Sort)); return(new SqlRootExpression(newTableExpressions, expression.ResourceTableExpressions)); }
public void GivenExpressionWithResourceColumnnAndChainedExpressions_WhenRewritten_ResourceColumnPredicatesPromotedToChainTableExpression(string paramName) { var inputExpression = new SqlRootExpression( new List <SearchParamTableExpression> { new SearchParamTableExpression( ChainLinkQueryGenerator.Instance, new SqlChainLinkExpression(new[] { "Observation" }, new SearchParameterInfo("myref", "myref"), new[] { "Patient" }, false), SearchParamTableExpressionKind.Chain, 1), new SearchParamTableExpression( null, new SearchParameterExpression(new SearchParameterInfo("myParam", "myParam"), Expression.Equals(FieldName.String, null, "foo")), SearchParamTableExpressionKind.Normal, 1), }, new List <SearchParameterExpressionBase> { new SearchParameterExpression(new SearchParameterInfo(paramName, paramName), Expression.Equals(FieldName.String, null, "ExtractableTestParamValue")), }); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(ResourceColumnPredicatePushdownRewriter.Instance); Assert.Equal(inputExpression.ResourceTableExpressions[0], ((SqlChainLinkExpression)visitedExpression.SearchParamTableExpressions[0].Predicate).ExpressionOnSource); Assert.Equal(inputExpression.SearchParamTableExpressions[0].ChainLevel, visitedExpression.SearchParamTableExpressions[0].ChainLevel); Assert.Same(inputExpression.SearchParamTableExpressions[1], visitedExpression.SearchParamTableExpressions[1]); }
public override Expression VisitSqlRoot(SqlRootExpression expression, object context) { List <SearchParamTableExpression> newTableExpressions = null; for (var i = 0; i < expression.SearchParamTableExpressions.Count; i++) { SearchParamTableExpression searchParamTableExpression = expression.SearchParamTableExpressions[i]; if (searchParamTableExpression.Kind != SearchParamTableExpressionKind.Chain) { newTableExpressions?.Add(searchParamTableExpression); continue; } EnsureAllocatedAndPopulated(ref newTableExpressions, expression.SearchParamTableExpressions, i); ProcessChainedExpression((ChainedExpression)searchParamTableExpression.Predicate, newTableExpressions, 1); } if (newTableExpressions == null) { return(expression); } return(new SqlRootExpression(newTableExpressions, expression.ResourceTableExpressions)); }
public void GivenExpressionWithNoTableExpressions_WhenRewritten_ReturnsOriginalExpression() { var inputExpression = SqlRootExpression.WithDenormalizedExpressions( Expression.Equals(FieldName.Number, null, 1)); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(DenormalizedPredicateRewriter.Instance); Assert.Equal(inputExpression, visitedExpression); }
public void GivenExpressionWithNoResourceColumnExpressions_WhenRewritten_ReturnsOriginalExpression() { var inputExpression = SqlRootExpression.WithSearchParamTableExpressions( new SearchParamTableExpression(null, null, SearchParamTableExpressionKind.Normal)); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(ResourceColumnPredicatePushdownRewriter.Instance); Assert.Equal(inputExpression, visitedExpression); }
public void GivenExpressionWithNoTableExpressions_WhenRewritten_ReturnsOriginalExpression() { var inputExpression = SqlRootExpression.WithResourceTableExpressions( Expression.SearchParameter(new SearchParameterInfo("abc", "abc"), Expression.Equals(FieldName.Number, null, 1))); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(ResourceColumnPredicatePushdownRewriter.Instance); Assert.Equal(inputExpression, visitedExpression); }
public void GivenExpressionWithSingleTableExpression_WhenReordered_ReturnsOriginalExpression() { var inputExpression = SqlRootExpression.WithTableExpressions( new TableExpression(null, null, null, TableExpressionKind.Normal)); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(NormalizedPredicateReorderer.Instance); Assert.Equal(inputExpression, visitedExpression); }
public Expression VisitSqlRoot(SqlRootExpression expression, object context) { if (expression.TableExpressions.Count == 0 || expression.DenormalizedExpressions.Count == 0 || expression.TableExpressions.All(t => t.Kind == TableExpressionKind.Chain)) { return(expression); } Expression extractedDenormalizedExpression = null; List <Expression> newDenormalizedPredicates = null; for (int i = 0; i < expression.DenormalizedExpressions.Count; i++) { Expression currentExpression = expression.DenormalizedExpressions[i]; if (currentExpression is SearchParameterExpression searchParameterExpression) { switch (searchParameterExpression.Parameter.Name) { case SqlSearchParameters.ResourceSurrogateIdParameterName: case SearchParameterNames.ResourceType: extractedDenormalizedExpression = extractedDenormalizedExpression == null ? currentExpression : Expression.And(extractedDenormalizedExpression, currentExpression); EnsureAllocatedAndPopulated(ref newDenormalizedPredicates, expression.DenormalizedExpressions, i); break; default: newDenormalizedPredicates?.Add(expression); break; } } } if (extractedDenormalizedExpression == null) { return(expression); } var newTableExpressions = new List <TableExpression>(expression.TableExpressions.Count); foreach (var tableExpression in expression.TableExpressions) { if (tableExpression.Kind == TableExpressionKind.Chain) { newTableExpressions.Add(tableExpression); } else { Expression newDenormalizedPredicate = tableExpression.DenormalizedPredicate == null ? extractedDenormalizedExpression : Expression.And(tableExpression.DenormalizedPredicate, extractedDenormalizedExpression); newTableExpressions.Add(new TableExpression(tableExpression.SearchParameterQueryGenerator, tableExpression.NormalizedPredicate, newDenormalizedPredicate, tableExpression.Kind)); } } return(new SqlRootExpression(newTableExpressions, newDenormalizedPredicates)); }
public override Expression VisitSqlRoot(SqlRootExpression expression, object context) { if (expression.TableExpressions.Count == 0) { return(expression); } List <TableExpression> newTableExpressions = null; for (var i = 0; i < expression.TableExpressions.Count; i++) { TableExpression tableExpression = expression.TableExpressions[i]; bool found = false; // The expressions contained within a ChainExpression // have been promoted to TableExpressions in this list. // Those are considered, not these. if (tableExpression.Kind != TableExpressionKind.Chain) { if (_rewritingScout != null) { var newNormalizedPredicate = tableExpression.NormalizedPredicate.AcceptVisitor(_rewritingScout, null); if (!ReferenceEquals(newNormalizedPredicate, tableExpression.NormalizedPredicate)) { found = true; tableExpression = new TableExpression(tableExpression.SearchParameterQueryGenerator, newNormalizedPredicate, tableExpression.DenormalizedPredicate, tableExpression.Kind, tableExpression.ChainLevel); } } else { found = tableExpression.NormalizedPredicate.AcceptVisitor(_booleanScout, null); } } if (found) { EnsureAllocatedAndPopulated(ref newTableExpressions, expression.TableExpressions, i); newTableExpressions.Add(tableExpression); newTableExpressions.Add((TableExpression)tableExpression.AcceptVisitor(this, context)); } else { newTableExpressions?.Add(tableExpression); } } if (newTableExpressions == null) { return(expression); } return(new SqlRootExpression(newTableExpressions, expression.DenormalizedExpressions)); }
public void GivenExpressionWithNoNotExpression_WhenVisited_OriginalExpressionReturned() { var searchParamTableExpressions = new List <SearchParamTableExpression> { new SearchParamTableExpression(null, null, SearchParamTableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithSearchParamTableExpressions(searchParamTableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(NotExpressionRewriter.Instance); Assert.Equal(inputExpression, visitedExpression); }
public void GivenExpressionWithNoMissingParameterExpression_WhenVisited_OriginalExpressionReturned() { var tableExpressions = new List <TableExpression> { new TableExpression(null, null, null, TableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(MissingSearchParamVisitor.Instance); Assert.Equal(inputExpression, visitedExpression); }
public void GivenExpressionWithMulthMultipleTableExpressions_WhenReordered_DenormilizedExpressionReturnedFirst() { var tableExpressions = new List <TableExpression> { new TableExpression(new ReferenceSearchParameterQueryGenerator(), NormalExpression, null, TableExpressionKind.Normal), new TableExpression(null, null, Expression.Equals(FieldName.String, null, "TestId"), TableExpressionKind.All), }; var inputExpression = SqlRootExpression.WithTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(NormalizedPredicateReorderer.Instance); Assert.Collection(visitedExpression.TableExpressions, new[] { 1, 0 }.Select <int, Action <TableExpression> >(x => e => Assert.Equal(tableExpressions[x], e)).ToArray()); }
public virtual Expression VisitSqlRoot(SqlRootExpression expression, TContext context) { IReadOnlyList <SearchParameterExpressionBase> visitedResourceExpressions = VisitArray(expression.ResourceTableExpressions, context); IReadOnlyList <SearchParamTableExpression> visitedTableExpressions = VisitArray(expression.SearchParamTableExpressions, context); if (ReferenceEquals(visitedTableExpressions, expression.SearchParamTableExpressions) && ReferenceEquals(visitedResourceExpressions, expression.ResourceTableExpressions)) { return(expression); } return(new SqlRootExpression(visitedTableExpressions, visitedResourceExpressions)); }
public void GivenExpressionWithMissingParameterExpressionFalseLast_WhenVisited_OriginalExpressionReturned() { var tableExpressions = new List <SearchParamTableExpression> { new SearchParamTableExpression(null, null, SearchParamTableExpressionKind.Normal), new SearchParamTableExpression(null, new MissingSearchParameterExpression(new SearchParameterInfo("TestParam", "TestParam"), false), SearchParamTableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithSearchParamTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(MissingSearchParamVisitor.Instance); Assert.Equal(inputExpression, visitedExpression); }
public virtual Expression VisitSqlRoot(SqlRootExpression expression, TContext context) { IReadOnlyList <Expression> denormalizedPredicates = VisitArray(expression.DenormalizedExpressions, context); IReadOnlyList <TableExpression> normalizedPredicates = VisitArray(expression.TableExpressions, context); if (ReferenceEquals(normalizedPredicates, expression.TableExpressions) && ReferenceEquals(denormalizedPredicates, expression.DenormalizedExpressions)) { return(expression); } return(new SqlRootExpression(normalizedPredicates, denormalizedPredicates)); }
public void GivenExpressionWithMultipleTableExpressions_WhenReordered_MissingParameterExpressionReturnedBeforeNotExpression() { var tableExpressions = new List <SearchParamTableExpression> { new SearchParamTableExpression(null, NotExpression, SearchParamTableExpressionKind.Normal), new SearchParamTableExpression(null, new MissingSearchParameterExpression(new SearchParameterInfo("TestParam"), true), SearchParamTableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithSearchParamTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(SearchParamTableExpressionReorderer.Instance); Assert.Collection(visitedExpression.SearchParamTableExpressions, new[] { 1, 0 }.Select <int, Action <SearchParamTableExpression> >(x => e => Assert.Equal(tableExpressions[x], e)).ToArray()); }
public void GivenExpressionWithMulthMultipleTableExpressions_WhenReordered_IncludeExpressionReturnedLast() { var tableExpressions = new List <TableExpression> { new TableExpression(new IncludeQueryGenerator(), null, null, TableExpressionKind.Include), new TableExpression(null, null, null, TableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(NormalizedPredicateReorderer.Instance); Assert.Collection(visitedExpression.TableExpressions, new[] { 1, 0 }.Select <int, Action <TableExpression> >(x => e => Assert.Equal(tableExpressions[x], e)).ToArray()); }
public void GivenExpressionWithMultipleTableExpressions_WhenReordered_CompartmentExpressionReturnedBeforeNormal() { var tableExpressions = new List <SearchParamTableExpression> { new SearchParamTableExpression(null, NormalExpression, SearchParamTableExpressionKind.Normal), new SearchParamTableExpression(new CompartmentQueryGenerator(), NormalExpression, SearchParamTableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithSearchParamTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(SearchParamTableExpressionReorderer.Instance); Assert.Collection(visitedExpression.SearchParamTableExpressions, new[] { 1, 0 }.Select <int, Action <SearchParamTableExpression> >(x => e => Assert.Equal(tableExpressions[x], e)).ToArray()); }
public override Expression VisitSqlRoot(SqlRootExpression expression, SearchOptions context) { if (context.CountOnly || expression.TableExpressions.Count == 0) { return(expression); } var newNormalizedPredicates = new List <TableExpression>(expression.TableExpressions.Count + 1); newNormalizedPredicates.AddRange(expression.TableExpressions); newNormalizedPredicates.Add(TopTableExpression); return(new SqlRootExpression(newNormalizedPredicates, expression.DenormalizedExpressions)); }
public void GivenExpressionExtractableDenormalizedExpression_WhenRewritten_ReturnsOriginalExpression() { var inputExpression = new SqlRootExpression( new List <TableExpression> { new TableExpression(null, null, null, TableExpressionKind.Normal), }, new List <Expression> { new SearchParameterExpression(new SearchParameterInfo("TestParamName"), Expression.Equals(FieldName.String, null, "TestParamValue")), }); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(DenormalizedPredicateRewriter.Instance); Assert.Equal(inputExpression, visitedExpression); }
public override Expression VisitSqlRoot(SqlRootExpression expression, SearchOptions context) { if (context.CountOnly || expression.SearchParamTableExpressions.Count == 0) { return(expression); } var newTableExpressions = new List <SearchParamTableExpression>(expression.SearchParamTableExpressions.Count + 1); newTableExpressions.AddRange(expression.SearchParamTableExpressions); newTableExpressions.Add(_topSearchParamTableExpression); return(new SqlRootExpression(newTableExpressions, expression.ResourceTableExpressions)); }
public void GivenSqlRootExpressionWithResourceColumnPredicateAndOnlyIncludeTableExpression_WhenRewritten_ResourceColumnIsPreserved() { var inputExpression = new SqlRootExpression( new List <SearchParamTableExpression> { new SearchParamTableExpression(null, null, SearchParamTableExpressionKind.Include), }, new List <SearchParameterExpressionBase> { new SearchParameterExpression(new SearchParameterInfo(SearchParameterNames.ResourceType, SearchParameterNames.ResourceType), Expression.Equals(FieldName.String, null, "TestParamValue1")), }); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(ResourceColumnPredicatePushdownRewriter.Instance); Assert.Same(inputExpression.ResourceTableExpressions, visitedExpression.ResourceTableExpressions); }
public void GivenSqlRootExpressionWithDenormalizedPredicateAndOnlyIncludeTableExpression_WhenRewritten_DenormalizedPredicateIsPreserved() { var inputExpression = new SqlRootExpression( new List <TableExpression> { new TableExpression(null, null, null, TableExpressionKind.Include), }, new List <Expression> { new SearchParameterExpression(new SearchParameterInfo(SearchParameterNames.ResourceType), Expression.Equals(FieldName.String, null, "TestParamValue1")), }); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(DenormalizedPredicateRewriter.Instance); Assert.Same(inputExpression.DenormalizedExpressions, visitedExpression.DenormalizedExpressions); }
public void GivenExpressionWithExtractableDenormalizedExpression_WhenRewritten_DenormalizedExpressionAddedToTableExpressions(string paramName) { var inputExpression = new SqlRootExpression( new List <TableExpression> { new TableExpression(null, null, null, TableExpressionKind.Normal), }, new List <Expression> { new SearchParameterExpression(new SearchParameterInfo(paramName), Expression.Equals(FieldName.String, null, "TestParamValue")), }); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(DenormalizedPredicateRewriter.Instance); Assert.Equal(inputExpression.DenormalizedExpressions[0], visitedExpression.TableExpressions[0].DenormalizedPredicate); }
public void GivenExpressionWithMissingParameterExpressionLast_WhenVisited_MissingParameterExpressionNegated() { var tableExpressions = new List <TableExpression> { new TableExpression(null, null, null, TableExpressionKind.Normal), new TableExpression(null, new MissingSearchParameterExpression(new SearchParameterInfo("TestParam"), true), null, TableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(MissingSearchParamVisitor.Instance); Assert.Collection( visitedExpression.TableExpressions, e => { Assert.Equal(tableExpressions[0], e); }, e => { Assert.Equal(TableExpressionKind.NotExists, e.Kind); }); }
public void GivenExpressionWithMissingParameterExpression_WhenVisited_AllExpressionPrependedToExpressionList() { var tableExpressions = new List <TableExpression> { new TableExpression(null, new MissingSearchParameterExpression(new SearchParameterInfo("TestParam"), true), null, TableExpressionKind.Normal), }; var inputExpression = SqlRootExpression.WithTableExpressions(tableExpressions); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(MissingSearchParamVisitor.Instance); Assert.Collection( visitedExpression.TableExpressions, e => { Assert.Equal(TableExpressionKind.All, e.Kind); }, e => { Assert.NotNull(e.NormalizedPredicate as MissingSearchParameterExpression); }); Assert.Equal(tableExpressions.Count + 1, visitedExpression.TableExpressions.Count); }
public void GivenExpressionWithMultipleExtractableDenormalizedExpressions_WhenRewritten_DenormalizedExpressionsAddedToTableExpressions() { var inputExpression = new SqlRootExpression( new List <TableExpression> { new TableExpression(null, null, null, TableExpressionKind.Normal), }, new List <Expression> { new SearchParameterExpression(new SearchParameterInfo(SearchParameterNames.ResourceType), Expression.Equals(FieldName.String, null, "TestParamValue1")), new SearchParameterExpression(new SearchParameterInfo(SqlSearchParameters.ResourceSurrogateIdParameterName), Expression.Equals(FieldName.String, null, "TestParamValue2")), }); var visitedExpression = (SqlRootExpression)inputExpression.AcceptVisitor(DenormalizedPredicateRewriter.Instance); Assert.Equal(Expression.And(inputExpression.DenormalizedExpressions).ToString(), visitedExpression.TableExpressions[0].DenormalizedPredicate.ToString()); }