private SearchParameterQueryGenerator GetSearchParameterQueryGenerator(SearchParameterExpressionBase searchParameter) { switch (searchParameter.Parameter.Name) { case SearchParameterNames.Id: return(ResourceIdParameterQueryGenerator.Instance); case SearchParameterNames.ResourceType: return(ResourceTypeIdParameterQueryGenerator.Instance); case SqlSearchParameters.ResourceSurrogateIdParameterName: return(ResourceSurrogateIdParameterQueryGenerator.Instance); default: throw new NotSupportedException(searchParameter.Parameter.Name); } }
private static SearchParameterQueryGenerator GetSearchParameterQueryGenerator(SearchParameterExpressionBase searchParameter) { return(GetSearchParameterQueryGeneratorIfResourceColumnSearchParameter(searchParameter) ?? throw new InvalidOperationException($"Unexpected search parameter {searchParameter.Parameter.Code}")); }
public override Expression VisitSqlRoot(SqlRootExpression expression, object context) { if (expression.SearchParamTableExpressions.Count == 0 || expression.ResourceTableExpressions.Count == 0 || expression.SearchParamTableExpressions.All(e => e.Kind == SearchParamTableExpressionKind.Include)) { // if only Include expressions, the case is handled in IncludeMatchSeedRewriter return(expression); } Expression extractedCommonResourceExpressions = null; bool containsResourceExpressionFoundOnlyOnResourceTable = false; for (int i = 0; i < expression.ResourceTableExpressions.Count; i++) { SearchParameterExpressionBase currentExpression = expression.ResourceTableExpressions[i]; if (currentExpression is SearchParameterExpression searchParameterExpression) { if (searchParameterExpression.Parameter.ColumnLocation().HasFlag(SearchParameterColumnLocation.SearchParamTable)) { extractedCommonResourceExpressions = extractedCommonResourceExpressions == null ? (Expression)currentExpression : Expression.And(extractedCommonResourceExpressions, currentExpression); } else { containsResourceExpressionFoundOnlyOnResourceTable = true; } } } var newTableExpressions = new List <SearchParamTableExpression>(expression.SearchParamTableExpressions.Count); if (containsResourceExpressionFoundOnlyOnResourceTable) { // There is a predicate over _id, which is on the Resource table but not on the search parameter tables. // So the first table expression should be an "All" expression, where we restrict the resultset to resources with that ID. newTableExpressions.Add(new SearchParamTableExpression(null, Expression.And(expression.ResourceTableExpressions), SearchParamTableExpressionKind.All)); } foreach (var tableExpression in expression.SearchParamTableExpressions) { if (tableExpression.Kind == SearchParamTableExpressionKind.Include || (tableExpression.Kind == SearchParamTableExpressionKind.Normal && tableExpression.ChainLevel > 0) || (tableExpression.Kind == SearchParamTableExpressionKind.Chain && tableExpression.ChainLevel > 1)) { // these predicates do not apply to referenced resources newTableExpressions.Add(tableExpression); } else if (tableExpression.Kind == SearchParamTableExpressionKind.Chain) { var sqlChainLinkExpression = (SqlChainLinkExpression)tableExpression.Predicate; Debug.Assert(sqlChainLinkExpression.ExpressionOnSource == null); var newChainLinkExpression = new SqlChainLinkExpression( sqlChainLinkExpression.ResourceTypes, sqlChainLinkExpression.ReferenceSearchParameter, sqlChainLinkExpression.TargetResourceTypes, sqlChainLinkExpression.Reversed, extractedCommonResourceExpressions, sqlChainLinkExpression.ExpressionOnTarget); newTableExpressions.Add(new SearchParamTableExpression(tableExpression.QueryGenerator, newChainLinkExpression, tableExpression.Kind, chainLevel: tableExpression.ChainLevel)); } else { Expression predicate = tableExpression.Predicate == null ? extractedCommonResourceExpressions : Expression.And(tableExpression.Predicate, extractedCommonResourceExpressions); newTableExpressions.Add(new SearchParamTableExpression(tableExpression.QueryGenerator, predicate, tableExpression.Kind, tableExpression.ChainLevel)); } } return(new SqlRootExpression(newTableExpressions, Array.Empty <SearchParameterExpressionBase>())); }
protected static SearchParameterQueryGenerator GetSearchParameterQueryGeneratorIfResourceColumnSearchParameter(SearchParameterExpressionBase searchParameter) { switch (searchParameter.Parameter.Code) { case SearchParameterNames.Id: return(ResourceIdParameterQueryGenerator.Instance); case SearchParameterNames.ResourceType: return(ResourceTypeIdParameterQueryGenerator.Instance); case SqlSearchParameters.ResourceSurrogateIdParameterName: return(ResourceSurrogateIdParameterQueryGenerator.Instance); case SqlSearchParameters.PrimaryKeyParameterName: return(PrimaryKeyRangeParameterQueryGenerator.Instance); #if DEBUG case SearchParameterNames.LastUpdated: throw new InvalidOperationException($"Expression with {SearchParameterNames.LastUpdated} parameter should have been rewritten to use {SqlSearchParameters.ResourceSurrogateIdParameterName}."); #endif default: return(null); } }