public object VisitSearchParameter(SearchParameterExpression expression, Context context) { switch (expression.Parameter.Code) { case SearchParameterNames.ResourceType: // We do not currently support specifying the system for the _type parameter value. // We would need to add it to the document, but for now it seems pretty unlikely that it will // be specified when searching. expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride((n, i) => SearchValueConstants.RootResourceTypeName)); break; case SearchParameterNames.LastUpdated: // For LastUpdate queries, the LastModified property on the root is // more performant than the searchIndices _lastUpdated.st and _lastUpdate.et // we will override the mapping for that expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride((n, i) => SearchValueConstants.LastModified)); break; case SearchValueConstants.TypeIdCompositeSearchParameterName: // This is an internal composite search parameter with components _type and _id, used when performing a query for includes. // We use the SearchValueConstants.RootResourceTypeName and SearchValueConstants.ResourceId fields respectively. expression.Expression.AcceptVisitor( this, context.WithFieldNameOverride( (fieldName, componentIndex) => componentIndex switch { 0 => SearchValueConstants.RootResourceTypeName, 1 => KnownResourceWrapperProperties.ResourceId, _ => throw new InvalidOperationException("unexpected component index"), })); break;
internal static void ValidateSearchParameterExpression(Expression expression, string paramName, Action <Expression> valueValidator) { SearchParameterExpression parameterExpression = Assert.IsType <SearchParameterExpression>(expression); Assert.Equal(paramName, parameterExpression.Parameter.Name); valueValidator(parameterExpression.Expression); }
public object VisitSearchParameter(SearchParameterExpression expression, Context context) { if (expression.Parameter.Name == SearchParameterNames.ResourceType) { // We do not currently support specifying the system for the _type parameter value. // We would need to add it to the document, but for now it seems pretty unlikely that it will // be specified when searching. expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride(SearchValueConstants.RootResourceTypeName)); } else if (expression.Parameter.Name == SearchParameterNames.LastUpdated) { // For LastUpdate queries, the LastModified property on the root is // more performant than the searchIndices _lastUpdated.st and _lastUpdate.et // we will override the mapping for that expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride(SearchValueConstants.LastModified)); } else { AppendSubquery(expression.Parameter.Name, expression.Expression, context); } _queryBuilder.AppendLine(); return(null); }
public override Expression VisitSearchParameter(SearchParameterExpression expression, object context) { if (expression.Parameter.Code == SearchParameterNames.LastUpdated) { return(Expression.SearchParameter(SqlSearchParameters.ResourceSurrogateIdParameter, expression.Expression.AcceptVisitor(this, context))); } return(expression); }
public override bool VisitSearchParameter(SearchParameterExpression expression, object context) { if (expression.Parameter.Type == SearchParamType.String || expression.Parameter.Type == SearchParamType.Composite) { return(expression.Expression.AcceptVisitor(this, expression.Parameter)); } return(false); }
public void GivenAnUntypedReferenceExpressionWithOneTargetType_WhenRewritten_ExpressionIncludesType() { SearchParameterExpression inputExpression = Expression.SearchParameter( ReferenceSearchParameterWithOneTargetType, Expression.StringEquals(FieldName.ReferenceResourceId, null, "myId", false)); Expression outputExpression = inputExpression.AcceptVisitor(UntypedReferenceRewriter.Instance); Assert.Equal("(Param p (And (StringEquals ReferenceResourceId 'myId') (StringEquals ReferenceResourceType 'Organization')))", outputExpression.ToString()); }
public void GivenAnUntypedReferenceExpressionWithMultipleTargetTypes_WhenRewritten_DoesNotChange() { SearchParameterExpression inputExpression = Expression.SearchParameter( ReferenceSearchParameterWithTwoTargetTypes, Expression.StringEquals(FieldName.ReferenceResourceId, null, "patientId", false)); Expression outputExpression = inputExpression.AcceptVisitor(UntypedReferenceRewriter.Instance); Assert.Same(inputExpression, outputExpression); }
public override Expression VisitSearchParameter(SearchParameterExpression expression, object context) { if (expression.Parameter.Type == SearchParamType.String || expression.Parameter.Type == SearchParamType.Composite) { return(base.VisitSearchParameter(expression, expression.Parameter)); } return(expression); }
public override Expression VisitSearchParameter(SearchParameterExpression expression, object context) { // include composites because they may contain dates. if (expression.Parameter.Type == SearchParamType.Date || expression.Parameter.Type == SearchParamType.Composite) { return(base.VisitSearchParameter(expression, context)); } return(expression); }
public override Expression VisitSearchParameter(SearchParameterExpression expression, object context) { // for now, we don't apply this optimization to composite parameters if (expression.Parameter.Type == SearchParamType.Date && expression.Expression is MultiaryExpression) { return(base.VisitSearchParameter(expression, context)); } return(expression); }
public void GivenATypedReferenceExpressionWithOneTargetType_WhenRewritten_DoesNotChange() { SearchParameterExpression inputExpression = Expression.SearchParameter( ReferenceSearchParameterWithOneTargetType, Expression.And( Expression.StringEquals(FieldName.ReferenceResourceType, null, "Organization", false), Expression.StringEquals(FieldName.ReferenceResourceId, null, "myId", false))); Expression outputExpression = inputExpression.AcceptVisitor(UntypedReferenceRewriter.Instance); Assert.Same(inputExpression, outputExpression); }
public override SearchParameterQueryGeneratorContext VisitSearchParameter(SearchParameterExpression expression, SearchParameterQueryGeneratorContext context) { short searchParamId = context.Model.GetSearchParamId(expression.Parameter.Url); SmallIntColumn searchParamIdColumn = VLatest.SearchParam.SearchParamId; context.StringBuilder .Append(searchParamIdColumn, context.TableAlias) .Append(" = ") .AppendLine(context.Parameters.AddParameter(searchParamIdColumn, searchParamId).ParameterName) .Append("AND "); return(expression.Expression.AcceptVisitor(this, context)); }
public void GivenAnUntypedReferenceExpressionWithOneTargetTypeInACompositeSearchParameter_WhenRewritten_ExpressionIncludesType() { SearchParameterExpression inputExpression = Expression.SearchParameter( CompositeParameter, Expression.And( Expression.StringEquals(FieldName.ReferenceResourceId, 0, "patientId", false), Expression.StringEquals(FieldName.ReferenceResourceId, 1, "orgId", false), Expression.Equals(FieldName.Number, 2, 8))); Expression outputExpression = inputExpression.AcceptVisitor(UntypedReferenceRewriter.Instance); Assert.Equal("(Param c (And (StringEquals [0].ReferenceResourceId 'patientId') (StringEquals [1].ReferenceResourceId 'orgId') (FieldEqual [2].Number 8) (StringEquals [1].ReferenceResourceType 'Organization')))", outputExpression.ToString()); }
public override Expression VisitSearchParameter(SearchParameterExpression expression, SqlSearchOptions context) { if (context.Sort.Count > 0) { if (expression.Parameter.Equals(context.Sort[0].searchParameterInfo)) { // We are returning null here to notify that we have found a SearchParameterExpression // for the same search parameter used for sort. return(null); } } return(expression); }
public void GivenATypedReferenceExpressionWithOneTargetTypeInACompositeSearchParameter_WhenRewritten_DoesNotChange() { SearchParameterExpression inputExpression = Expression.SearchParameter( CompositeParameter, Expression.And( Expression.StringEquals(FieldName.ReferenceResourceId, 0, "patientId", false), Expression.StringEquals(FieldName.ReferenceResourceType, 1, "Organization", false), Expression.StringEquals(FieldName.ReferenceResourceId, 1, "orgId", false), Expression.Equals(FieldName.Number, 2, 8))); Expression outputExpression = inputExpression.AcceptVisitor(UntypedReferenceRewriter.Instance); Assert.Same(inputExpression, outputExpression); }
public object VisitSearchParameter(SearchParameterExpression expression, Context context) { switch (expression.Parameter.Code) { case SearchParameterNames.ResourceType: // We do not currently support specifying the system for the _type parameter value. // We would need to add it to the document, but for now it seems pretty unlikely that it will // be specified when searching. expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride((n, i) => SearchValueConstants.RootResourceTypeName)); break; case SearchParameterNames.Id: expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride((n, i) => KnownResourceWrapperProperties.ResourceId)); break; case SearchParameterNames.LastUpdated: // For LastUpdate queries, the LastModified property on the root is // more performant than the searchIndices _lastUpdated.st and _lastUpdate.et // we will override the mapping for that expression.Expression.AcceptVisitor(this, context.WithFieldNameOverride((n, i) => SearchValueConstants.LastModified)); break; case SearchValueConstants.WildcardReferenceSearchParameterName: // This is an internal search parameter that that matches any reference search parameter. // It is used for wildcard revinclude queries AppendSubquery(parameterName: null, expression.Expression, context); break; default: if (expression.Expression is NotExpression notExpression) { AppendSubquery(expression.Parameter.Code, notExpression.Expression, context, true); } else { AppendSubquery(expression.Parameter.Code, expression.Expression, context); } break; } _queryBuilder.AppendLine(); return(null); }
public override SearchParameterQueryGeneratorContext VisitSearchParameter(SearchParameterExpression expression, SearchParameterQueryGeneratorContext context) { SearchParameterQueryGenerator delegatedGenerator = GetSearchParameterQueryGeneratorIfResourceColumnSearchParameter(expression); if (delegatedGenerator != null) { // This is a search parameter over a column that exists on the Resource table or both the Resource table and search parameter tables. // Delegate to the visitor specific to it. return(expression.Expression.AcceptVisitor(delegatedGenerator, context)); } short searchParamId = context.Model.GetSearchParamId(expression.Parameter.Url); SmallIntColumn searchParamIdColumn = VLatest.SearchParam.SearchParamId; context.StringBuilder .Append(searchParamIdColumn, context.TableAlias) .Append(" = ") .AppendLine(context.Parameters.AddParameter(searchParamIdColumn, searchParamId, true).ParameterName) .Append("AND "); return(expression.Expression.AcceptVisitor(this, context)); }
public void Visit(SearchParameterExpression expression) { if (expression.Parameter.Name == SearchParameterNames.ResourceType) { try { // We do not currently support specifying the system for the _type parameter value. // We would need to add it to the document, but for now it seems pretty unlikely that it will // be specified when searching. _fieldNameOverride = SearchValueConstants.RootResourceTypeName; expression.Expression.AcceptVisitor(this); } finally { _fieldNameOverride = null; } } else { AppendSubquery(expression.Parameter.Name, expression.Expression); } _queryBuilder.AppendLine(); }
public override SearchParameterQueryGeneratorContext VisitSearchParameter(SearchParameterExpression expression, SearchParameterQueryGeneratorContext context) { return(expression.Expression.AcceptVisitor(GetSearchParameterQueryGenerator(expression), context)); }
public override bool VisitSearchParameter(SearchParameterExpression expression, object context) => expression.Parameter.Name == SearchParameterNames.Id;
public SearchParamTableExpressionQueryGenerator VisitSearchParameter(SearchParameterExpression expression, object context) { return(VisitSearchParameterExpressionBase(expression.Parameter, expression.Expression, context)); }
public override Expression VisitSearchParameter(SearchParameterExpression expression, object context) { // Handle reference search parameters as well as composite search parameters with one or more reference components. // We first create a bitmask with bits set representing the component indexes that are candidates for this rule. // Bit 0 is for reference, non-composite parameters where the reference is of a single possible type // Bits 1 and up represent the component indexes (plus one) where the component is a reference search parameter with one type int componentCandidates = expression.Parameter.Type switch { SearchParamType.Reference when expression.Parameter.TargetResourceTypes?.Count == 1 => 1, SearchParamType.Composite => expression.Parameter.Component.Aggregate( (index: 1, flags: 0), (acc, c) => (index: acc.index + 1, flags: acc.flags | (c.ResolvedSearchParameter.Type == SearchParamType.Reference && c.ResolvedSearchParameter.TargetResourceTypes?.Count == 1 ? 1 << acc.index : 0))) .flags, _ => 0, }; if (componentCandidates == 0) { // nothing to do for this expression return(expression); } if (expression.Expression is MultiaryExpression multiaryExpression && multiaryExpression.MultiaryOperation == MultiaryOperator.Or) { Expression[] rewrittenExpressions = null; for (var i = 0; i < multiaryExpression.Expressions.Count; i++) { Expression subexpression = multiaryExpression.Expressions[i]; Expression rewrittenSubexpression = RewriteSubexpression(expression.Parameter, subexpression, componentCandidates); if (!ReferenceEquals(rewrittenSubexpression, subexpression)) { EnsureAllocatedAndPopulated(ref rewrittenExpressions, multiaryExpression.Expressions, i); } if (rewrittenExpressions != null) { rewrittenExpressions[i] = rewrittenSubexpression; } } if (rewrittenExpressions == null) { return(expression); } return(Expression.SearchParameter(expression.Parameter, Expression.Or(rewrittenExpressions))); } // a single expression (possibly ANDs), not multiple expressions ORed together Expression rewrittenExpression = RewriteSubexpression(expression.Parameter, expression.Expression, componentCandidates); if (ReferenceEquals(rewrittenExpression, expression.Expression)) { return(expression); } return(Expression.SearchParameter(expression.Parameter, rewrittenExpression)); }
public NormalizedSearchParameterQueryGenerator VisitSearchParameter(SearchParameterExpression expression, object context) { return(VisitSearchParameterExpressionBase(expression.Parameter, expression.Expression, context)); }