public override bool IsServerDelegatable(CallNode callNode, TexlBinding binding) { Contracts.AssertValue(callNode); Contracts.AssertValue(binding); if (!CheckArgsCount(callNode, binding)) { return(false); } IExternalDataSource dataSource = null; // We ensure Document is available because some tests run with a null Document. if ((binding.Document != null && !binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled) || !TryGetValidDataSourceForDelegation(callNode, binding, FunctionDelegationCapability, out dataSource)) { if (dataSource != null && dataSource.IsDelegatable) { binding.ErrorContainer.EnsureError(DocumentErrorSeverity.Warning, callNode, TexlStrings.OpNotSupportedByServiceSuggestionMessage_OpNotSupportedByService, Name); } return(false); } TexlNode[] args = callNode.Args.Children.VerifyValue(); if (args.Length == 0) { return(false); } // Don't delegate 1-N/N-N counts // TASK 9966488: Enable CountRows/CountIf delegation for table relationships if (binding.GetType(args[0]).HasExpandInfo) { SuggestDelegationHint(callNode, binding); return(false); } FilterOpMetadata metadata = dataSource.DelegationMetadata.FilterDelegationMetadata; // Validate for each predicate node. for (int i = 1; i < args.Length; i++) { if (!IsValidDelegatableFilterPredicateNode(args[i], binding, metadata)) { SuggestDelegationHint(callNode, binding); return(false); } } return(true); }
// Verifies if given callnode can be server delegatable or not. // Return true if // - Arg0 is delegatable ds and supports filter operation. // - All predicates to filter are delegatable if each firstname/binary/unary/dottedname/call node in each predicate satisfies delegation criteria set by delegation strategy for each node. public override bool IsServerDelegatable(CallNode callNode, TexlBinding binding) { Contracts.AssertValue(callNode); Contracts.AssertValue(binding); if (!CheckArgsCount(callNode, binding)) { return(false); } IExternalDataSource dataSource; FilterOpMetadata metadata = null; IDelegationMetadata delegationMetadata = null; if (TryGetEntityMetadata(callNode, binding, out delegationMetadata)) { if (!binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled || !TryGetValidDataSourceForDelegation(callNode, binding, DelegationCapability.ArrayLookup, out _)) { SuggestDelegationHint(callNode, binding); return(false); } metadata = delegationMetadata.FilterDelegationMetadata.VerifyValue(); } else { if (!TryGetValidDataSourceForDelegation(callNode, binding, FunctionDelegationCapability, out dataSource)) { return(false); } metadata = dataSource.DelegationMetadata.FilterDelegationMetadata; } TexlNode[] args = callNode.Args.Children.VerifyValue(); if (args.Length > 2 && binding.IsDelegatable(args[2])) { SuggestDelegationHint(args[2], binding); return(false); } if (args.Length < 2) { return(false); } return(IsValidDelegatableFilterPredicateNode(args[1], binding, metadata)); }
protected bool IsValidDelegatableFilterPredicateNode(TexlNode dsNode, TexlBinding binding, FilterOpMetadata filterMetadata) { Contracts.AssertValue(dsNode); Contracts.AssertValue(binding); Contracts.AssertValue(filterMetadata); var firstNameStrategy = GetFirstNameNodeDelegationStrategy(); var dottedNameStrategy = GetDottedNameNodeDelegationStrategy(); var cNodeStrategy = GetCallNodeDelegationStrategy(); NodeKind kind; kind = dsNode.Kind; switch (kind) { case NodeKind.BinaryOp: { BinaryOpNode opNode = dsNode.AsBinaryOp(); var binaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op, opNode); Contracts.AssertValue(opNode); if (!binaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, filterMetadata, binding)) { return(false); } break; } case NodeKind.FirstName: { if (!firstNameStrategy.IsValidFirstNameNode(dsNode.AsFirstName(), binding, null)) { return(false); } break; } case NodeKind.DottedName: { if (!dottedNameStrategy.IsValidDottedNameNode(dsNode.AsDottedName(), binding, filterMetadata, null)) { return(false); } break; } case NodeKind.UnaryOp: { UnaryOpNode opNode = dsNode.AsUnaryOpLit(); var unaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op); Contracts.AssertValue(opNode); if (!unaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, filterMetadata, binding)) { SuggestDelegationHint(dsNode, binding); return(false); } break; } case NodeKind.Call: { if (!cNodeStrategy.IsValidCallNode(dsNode.AsCall(), binding, filterMetadata)) { return(false); } break; } default: { if (kind != NodeKind.BoolLit) { SuggestDelegationHint(dsNode, binding, string.Format("Not supported node {0}.", kind)); return(false); } break; } } return(true); }