コード例 #1
0
        public bool IsValidCallNode(CallNode node, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (!IsValidNode(node, binding))
            {
                SuggestDelegationHint(node, binding);
                return(false);
            }

            // If the node is not row scoped and it's valid then it can be delegated.
            var isRowScoped = binding.IsRowScope(node);

            if (!isRowScoped)
            {
                return(true);
            }

            CallInfo callInfo = binding.GetInfo(node);

            if (callInfo?.Function != null && ((TexlFunction)callInfo.Function).IsRowScopedServerDelegatable(node, binding, metadata))
            {
                return(true);
            }

            var telemetryMessage = string.Format("Kind:{0}, isRowScoped:{1}", node.Kind, isRowScoped);

            SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
            TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.UndelegatableFunction, node, binding, _function, DelegationTelemetryInfo.CreateUndelegatableFunctionTelemetryInfo((TexlFunction)callInfo?.Function));
            return(false);
        }
コード例 #2
0
        public virtual bool IsSupportedOpNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);

            UnaryOpNode unaryOpNode = node.AsUnaryOpLit();

            if (unaryOpNode == null)
            {
                return(false);
            }

            if (!IsValidNode(node, binding))
            {
                return(false);
            }

            IOpDelegationStrategy opDelStrategy = _function.GetOpDelegationStrategy(unaryOpNode.Op);
            var unaryOpDelStrategy = (opDelStrategy as UnaryOpDelegationStrategy).VerifyValue();

            Contracts.Assert(unaryOpDelStrategy.Op == unaryOpNode.Op);

            if ((unaryOpNode.Child.Kind != NodeKind.FirstName) && !opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
            {
                var telemetryMessage = string.Format("{0} operator not supported at table level", unaryOpNode.Op.ToString());
                SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
                TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.UnaryOpNotSupportedByTable, node, binding, _function, DelegationTelemetryInfo.CreateUnaryOpNoSupportedInfoTelemetryInfo(unaryOpNode.Op));
                return(false);
            }

            return(IsSupportedNode(unaryOpNode.Child, metadata, binding, opDelStrategy));
        }
コード例 #3
0
        public override bool IsSupportedOpNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);

            BinaryOpNode binaryOpNode = node?.AsBinaryOp();

            if (binaryOpNode == null)
            {
                return(false);
            }

            var isRHSDelegableTable = IsRHSDelegableTable(binding, binaryOpNode, metadata);

            DName         columnName = default;
            FirstNameInfo info       = null;

            bool isFullyQualifiedFieldAccess = CheckForFullyQualifiedFieldAccess(isRHSDelegableTable, binaryOpNode, binding, node, ref columnName, ref info);

            if (!isFullyQualifiedFieldAccess)
            {
                return(false);
            }

            bool isRowScopedOrLambda = IsRowScopedOrLambda(binding, node, info, columnName, metadata);

            if (!isRowScopedOrLambda)
            {
                return(false);
            }

            return(base.IsSupportedOpNode(node, metadata, binding));
        }
コード例 #4
0
        private bool DoCoercionCheck(BinaryOpNode binaryOpNode, OperationCapabilityMetadata metadata, TexlBinding binding)
        {
            Contracts.AssertValue(binaryOpNode);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);

            DType leftType  = binding.GetType(binaryOpNode.Left);
            DType rightType = binding.GetType(binaryOpNode.Right);

            switch (leftType.Kind)
            {
            case DKind.Date:
                if (rightType.Kind == DKind.DateTime)
                {
                    // If rhs is a column of type DateTime and lhs is row scoped then we will need to apply the coercion on rhs. So check if coercion function date is supported or not.
                    if (IsColumnNode(binaryOpNode.Right, binding) && binding.IsRowScope(binaryOpNode.Left))
                    {
                        return(IsDelegatableColumnNode(binaryOpNode.Right.AsFirstName(), binding, null, DelegationCapability.Date));
                    }

                    // If lhs is rowscoped but not a field reference and rhs is rowscoped then we need to check if it's supported at table level.
                    if (binding.IsRowScope(binaryOpNode.Left) && binding.IsRowScope(binaryOpNode.Right))
                    {
                        return(metadata.IsDelegationSupportedByTable(DelegationCapability.Date));
                    }

                    return(true);
                }

                break;

            case DKind.DateTime:
                if (rightType.Kind == DKind.Date)
                {
                    // If lhs is a column of type DateTime and RHS is also row scoped then check if coercion function date is supported or not.
                    if (IsColumnNode(binaryOpNode.Left, binding) && binding.IsRowScope(binaryOpNode.Right))
                    {
                        return(IsDelegatableColumnNode(binaryOpNode.Left.AsFirstName(), binding, null, DelegationCapability.Date));
                    }

                    // If lhs is rowscoped but not a field reference and rhs is rowscoped then we need to check if it's supported at table level.
                    if (binding.IsRowScope(binaryOpNode.Left) && binding.IsRowScope(binaryOpNode.Right))
                    {
                        return(metadata.IsDelegationSupportedByTable(DelegationCapability.Date));
                    }

                    return(true);
                }

                break;

            default:
                break;
            }

            return(true);
        }
コード例 #5
0
        public virtual bool IsOpSupportedByColumn(OperationCapabilityMetadata metadata, TexlNode column, DPath columnPath, TexlBinding binder)
        {
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(column);
            Contracts.AssertValue(binder);

            var result = metadata.IsUnaryOpInDelegationSupportedByColumn(_unaryOp, columnPath);

            if (!result)
            {
                TrackingProvider.Instance.AddSuggestionMessage(FormatTelemetryMessage("Operator not supported by column."), column, binder);
            }

            return(result);
        }
コード例 #6
0
        public virtual bool IsOpSupportedByColumn(OperationCapabilityMetadata metadata, TexlNode column, DPath columnPath, TexlBinding binder)
        {
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(column);
            Contracts.AssertValue(binder);

            var result = metadata.IsBinaryOpInDelegationSupportedByColumn(_binaryOp, columnPath);

            if (!result)
            {
                TrackingProvider.Instance.AddSuggestionMessage(FormatTelemetryMessage("Operator not supported by column."), column, binder);
                SuggestDelegationHint(column, binder, TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn, CharacterUtils.MakeSafeForFormatString(columnPath.ToString()));
            }

            return(result);
        }
コード例 #7
0
        public virtual bool IsOpSupportedByTable(OperationCapabilityMetadata metadata, TexlNode node, TexlBinding binding)
        {
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);

            if (!metadata.IsBinaryOpInDelegationSupported(_binaryOp))
            {
                SuggestDelegationHint(node, binding, TexlStrings.OpNotSupportedByClientSuggestionMessage_OpNotSupportedByClient, _binaryOp.ToString());
                return(false);
            }

            if (!metadata.IsBinaryOpSupportedByTable(_binaryOp))
            {
                SuggestDelegationHint(node, binding, TexlStrings.OpNotSupportedByServiceSuggestionMessage_OpNotSupportedByService, _binaryOp.ToString());
                return(false);
            }

            return(true);
        }
コード例 #8
0
        private bool IsSupportedNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding, IOpDelegationStrategy opDelStrategy)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(opDelStrategy);

            if (!binding.IsRowScope(node))
            {
                return(true);
            }

            switch (node.Kind)
            {
            case NodeKind.DottedName:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var dottedNodeValStrategy = _function.GetDottedNameNodeDelegationStrategy();
                return(dottedNodeValStrategy.IsValidDottedNameNode(node.AsDottedName(), binding, metadata, opDelStrategy));
            }

            case NodeKind.Call:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var cNodeValStrategy = _function.GetCallNodeDelegationStrategy();
                return(cNodeValStrategy.IsValidCallNode(node.AsCall(), binding, metadata));
            }

            case NodeKind.FirstName:
            {
                var firstNameNodeValStrategy = _function.GetFirstNameNodeDelegationStrategy();
                return(firstNameNodeValStrategy.IsValidFirstNameNode(node.AsFirstName(), binding, opDelStrategy));
            }

            case NodeKind.UnaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                UnaryOpNode unaryOpNode = node.AsUnaryOpLit().VerifyValue();
                opDelStrategy = _function.GetOpDelegationStrategy(unaryOpNode.Op).VerifyValue();

                var unaryOpDelStrategy = (opDelStrategy as UnaryOpDelegationStrategy).VerifyValue();
                Contracts.Assert(unaryOpDelStrategy.Op == unaryOpNode.Op);

                if (!opDelStrategy.IsSupportedOpNode(node, metadata, binding))
                {
                    SuggestDelegationHint(node, binding);
                    return(false);
                }

                return(true);
            }

            case NodeKind.BinaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var binaryOpNode = node.AsBinaryOp().VerifyValue();
                IOpDelegationStrategy binaryOpNodeDelValidationStrategy = _function.GetOpDelegationStrategy(binaryOpNode.Op, binaryOpNode);
                return(binaryOpNodeDelValidationStrategy.IsSupportedOpNode(node.AsBinaryOp(), metadata, binding));
            }
            }

            SuggestDelegationHint(node, binding);
            return(false);
        }
コード例 #9
0
        protected bool IsRowScopedServerDelegatableHelper(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (binding.ErrorContainer.HasErrors(callNode) ||
                !CheckArgsCount(callNode, binding) ||
                !binding.IsRowScope(callNode))
            {
                return(false);
            }

            TexlNode[] args = callNode.Args.Children.VerifyValue();
            Contracts.Assert(args.Length == MinArity);

            if (binding.IsRowScope(args[1]))
            {
                binding.ErrorContainer.EnsureError(DocumentErrorSeverity.Warning, args[1], TexlStrings.SuggestRemoteExecutionHint_StringMatchSecondParam, Name);
                return(false);
            }

            foreach (var arg in args)
            {
                NodeKind argKind = arg.VerifyValue().Kind;
                switch (argKind)
                {
                case NodeKind.FirstName:
                    var firstNameStrategy = GetFirstNameNodeDelegationStrategy();
                    if (!firstNameStrategy.IsValidFirstNameNode(arg.AsFirstName(), binding, null))
                    {
                        return(false);
                    }
                    break;

                case NodeKind.Call:
                    if (!metadata.IsDelegationSupportedByTable(FunctionDelegationCapability))
                    {
                        return(false);
                    }

                    var cNodeStrategy = GetCallNodeDelegationStrategy();
                    if (!cNodeStrategy.IsValidCallNode(arg.AsCall(), binding, metadata))
                    {
                        return(false);
                    }
                    break;

                case NodeKind.StrLit:
                    break;

                case NodeKind.DottedName:
                {
                    var dottedStrategy = GetDottedNameNodeDelegationStrategy();
                    return(dottedStrategy.IsValidDottedNameNode(arg.AsDottedName(), binding, metadata, null));
                }

                default:
                    return(false);
                }
            }

            return(true);
        }
コード例 #10
0
        public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (binding.ErrorContainer.HasErrors(callNode) ||
                !CheckArgsCount(callNode, binding) ||
                !binding.IsRowScope(callNode))
            {
                return(false);
            }

            TexlNode[] args = callNode.Args.Children.VerifyValue();
            Contracts.Assert(args.Length >= MinArity);

            DelegationCapability funcDelegationCapability = FunctionDelegationCapability | (_isAnd ? DelegationCapability.And : DelegationCapability.Or);

            if (!metadata.IsDelegationSupportedByTable(funcDelegationCapability))
            {
                return(false);
            }

            foreach (var arg in args)
            {
                NodeKind argKind = arg.VerifyValue().Kind;
                switch (argKind)
                {
                case NodeKind.FirstName:
                {
                    var firstNameStrategy = GetFirstNameNodeDelegationStrategy();
                    if (!firstNameStrategy.IsValidFirstNameNode(arg.AsFirstName(), binding, null))
                    {
                        return(false);
                    }

                    break;
                }

                case NodeKind.Call:
                {
                    var cNodeStrategy = GetCallNodeDelegationStrategy();
                    if (!cNodeStrategy.IsValidCallNode(arg.AsCall(), binding, metadata))
                    {
                        SuggestDelegationHint(arg, binding);
                        return(false);
                    }

                    break;
                }

                case NodeKind.DottedName:
                {
                    var dottedStrategy = GetDottedNameNodeDelegationStrategy();
                    if (!dottedStrategy.IsValidDottedNameNode(arg.AsDottedName(), binding, metadata, null))
                    {
                        SuggestDelegationHint(arg, binding);
                        return(false);
                    }

                    break;
                }

                case NodeKind.BinaryOp:
                {
                    BinaryOpNode opNode = arg.AsBinaryOp();
                    var          binaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op, opNode);
                    if (!binaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, metadata, binding))
                    {
                        SuggestDelegationHint(arg, binding);
                        return(false);
                    }

                    break;
                }

                case NodeKind.UnaryOp:
                {
                    UnaryOpNode opNode = arg.AsUnaryOpLit();
                    var         unaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op);
                    if (!unaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, metadata, binding))
                    {
                        SuggestDelegationHint(arg, binding);
                        return(false);
                    }

                    break;
                }

                case NodeKind.BoolLit:
                    break;

                default:
                    return(false);
                }
            }

            return(true);
        }
コード例 #11
0
ファイル: Len.cs プロジェクト: jgrisham/Power-Fx
 public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
 {
     return(base.IsRowScopedServerDelegatable(callNode, binding, metadata));
 }
コード例 #12
0
ファイル: Trim.cs プロジェクト: jgrisham/Power-Fx
        public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            return(base.IsRowScopedServerDelegatable(callNode, binding, metadata));
        }
コード例 #13
0
        private bool IsValidRowScopedDottedNameNode(DottedNameNode node, TexlBinding binding, OperationCapabilityMetadata metadata, out bool isRowScopedDelegationExempted)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);

            isRowScopedDelegationExempted = false;
            if (node.Left.Kind == NodeKind.FirstName &&
                binding.IsDelegationExempted(node.Left as FirstNameNode) &&
                binding.IsLambdaScoped(node.Left as FirstNameNode))
            {
                isRowScopedDelegationExempted = true;

                return(true);
            }

            if (node.Left.Kind == NodeKind.DottedName)
            {
                return(IsValidRowScopedDottedNameNode(node.Left.AsDottedName(), binding, metadata, out isRowScopedDelegationExempted));
            }

            if (node.Left.Kind == NodeKind.Call && binding.GetInfo(node.Left as CallNode).Function is AsTypeFunction)
            {
                return(IsValidCallNode(node.Left as CallNode, binding, metadata));
            }

            // We only allow dotted or firstname node on LHS for now, with exception of AsType.
            return(node.Left.Kind == NodeKind.FirstName);
        }
コード例 #14
0
        public bool IsValidDottedNameNode(DottedNameNode node, TexlBinding binding, OperationCapabilityMetadata metadata, IOpDelegationStrategy opDelStrategy)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);
            Contracts.AssertValueOrNull(opDelStrategy);

            var isRowScoped = binding.IsRowScope(node);

            if (!isRowScoped)
            {
                return(IsValidNode(node, binding));
            }

            bool isRowScopedDelegationExempted;

            if (!IsValidRowScopedDottedNameNode(node, binding, metadata, out isRowScopedDelegationExempted))
            {
                var telemetryMessage = string.Format("Kind:{0}, isRowScoped:{1}",
                                                     node.Kind, isRowScoped);

                SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
                return(false);
            }

            if (isRowScopedDelegationExempted)
            {
                binding.SetBlockScopedConstantNode(node);
                return(true);
            }

            if (binding.TryGetFullRecordRowScopeAccessInfo(node, out var firstNameInfo))
            {
                // This means that this row scoped field is from some parent scope which is non-delegatable. That should deny delegation at that point.
                // For this scope, this means that value will be provided from some other source.
                // For example, AddColumns(CDS As Left, "Column1", LookUp(CDS1, Left.Name in FirstName))
                // CDS - *[Name:s], CDS1 - *[FirstName:s]
                if (GetCapabilityMetadata(firstNameInfo) == null)
                {
                    return(true);
                }
            }

            if (!binding.GetType(node.Left).HasExpandInfo)
            {
                DPath columnPath;
                if (!BinderUtils.TryConvertNodeToDPath(binding, node, out columnPath) || !metadata.IsDelegationSupportedByColumn(columnPath, _function.FunctionDelegationCapability))
                {
                    var safeColumnName = CharacterUtils.MakeSafeForFormatString(columnPath.ToDottedSyntax());
                    var message        = string.Format(StringResources.Get(TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn), safeColumnName);
                    SuggestDelegationHintAndAddTelemetryMessage(node, binding, message, TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn, safeColumnName);
                    TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.NoDelSupportByColumn, node, binding, _function, DelegationTelemetryInfo.CreateNoDelSupportByColumnTelemetryInfo(columnPath.ToDottedSyntax()));
                    return(false);
                }

                // If there is any operator applied on this node then check if column supports operation.
                return(opDelStrategy?.IsOpSupportedByColumn(metadata, node, columnPath, binding) ?? true);
            }

            // If there is an entity reference then we need to do additional verification.
            IExpandInfo info           = binding.GetType(node.Left).ExpandInfo.VerifyValue();
            var         dataSourceInfo = info.ParentDataSource;

            IDataEntityMetadata entityMetadata;

            if (!dataSourceInfo.DataEntityMetadataProvider.TryGetEntityMetadata(info.Identity, out entityMetadata))
            {
                var telemetryMessage = string.Format("Kind:{0}, isRowScoped:{1}, no metadata found for entity {2}",
                                                     node.Kind, isRowScoped, CharacterUtils.MakeSafeForFormatString(info.Identity));

                SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
                return(false);
            }

            OperationCapabilityMetadata entityCapabilityMetadata = GetScopedOperationCapabilityMetadata(entityMetadata.DelegationMetadata);
            string maybeLogicalName;
            DName  columnName = node.Right.Name;

            if (entityMetadata.DisplayNameMapping.TryGetFromSecond(node.Right.Name.Value, out maybeLogicalName))
            {
                columnName = new DName(maybeLogicalName);
            }

            var entityColumnPath = DPath.Root.Append(columnName);

            if (!entityCapabilityMetadata.IsDelegationSupportedByColumn(entityColumnPath, _function.FunctionDelegationCapability))
            {
                var safeColumnName = CharacterUtils.MakeSafeForFormatString(columnName.Value);
                var message        = string.Format(StringResources.Get(TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn), safeColumnName);
                SuggestDelegationHintAndAddTelemetryMessage(node, binding, message, TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn, safeColumnName);
                TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.NoDelSupportByColumn, node, binding, _function, DelegationTelemetryInfo.CreateNoDelSupportByColumnTelemetryInfo(columnName));
                return(false);
            }

            // If there is any operator applied on this node then check if column supports operation.
            return(opDelStrategy?.IsOpSupportedByColumn(entityCapabilityMetadata, node, entityColumnPath, binding) ?? true);
        }
コード例 #15
0
        public bool IsRHSDelegableTable(TexlBinding binding, BinaryOpNode binaryOpNode, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(binding);
            Contracts.AssertValue(binaryOpNode);
            Contracts.AssertValue(metadata);

            var rightNodeType = binding.GetType(binaryOpNode.Right);

            var hasEnhancedDelegation = binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled;
            var isColumn = rightNodeType?.IsColumn == true;
            var isDelegationSupportedByTable = metadata.IsDelegationSupportedByTable(DelegationCapability.CdsIn);
            var HasLeftFirstNameNodeOrIsFullRecordRowScopeAccess = binaryOpNode.Left?.AsFirstName() != null || binding.IsFullRecordRowScopeAccess(binaryOpNode.Left);

            return(hasEnhancedDelegation && isColumn && isDelegationSupportedByTable && HasLeftFirstNameNodeOrIsFullRecordRowScopeAccess);
        }
コード例 #16
0
        // Verifies if given kind of node is supported by function delegation.
        private bool IsSupportedNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding, IOpDelegationStrategy opDelStrategy, bool isRHSNode)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(opDelStrategy);

            if (!binding.IsRowScope(node))
            {
                // Check whether this is -
                //  1) in operator delegation and
                //  2) it is verifying if RHS node is supported and
                //  3) it is not an async node and
                //  4) it is a single column table and
                //  5) metadata belongs to cds datasource that supports delegation of CdsIn
                // If this check fails, verify if it is simply a valid node..
                // Eg of valid delegation functions -
                // Filter(Accounts, 'Account Name' in ["Foo", Bar"]) - Direct table use
                // Set(Names, ["Foo", Bar"]); Filter(Accounts, 'Account Name' in Names) - Using variable of type table
                // ClearCollect(Names, Accounts); Filter(Accounts, 'Account Name' in Names.'Account Name') - using column from collection.
                // This won't be delegated - Filter(Accounts, 'Account Name' in Accounts.'Account Name') as Accounts.'Account Name' is async.
                if ((binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled &&
                     isRHSNode && (opDelStrategy as BinaryOpDelegationStrategy)?.Op == BinaryOp.In && !binding.IsAsync(node) && binding.GetType(node).IsTable&& binding.GetType(node).IsColumn&&
                     metadata.IsDelegationSupportedByTable(DelegationCapability.CdsIn)) ||
                    IsValidNode(node, binding))
                {
                    return(true);
                }
            }

            switch (node.Kind)
            {
            case NodeKind.DottedName:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var dottedNodeValStrategy = _function.GetDottedNameNodeDelegationStrategy();
                return(dottedNodeValStrategy.IsValidDottedNameNode(node.AsDottedName(), binding, metadata, opDelStrategy));
            }

            case NodeKind.Call:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var cNodeValStrategy = _function.GetCallNodeDelegationStrategy();
                return(cNodeValStrategy.IsValidCallNode(node.AsCall(), binding, metadata));
            }

            case NodeKind.FirstName:
            {
                var firstNameNodeValStrategy = _function.GetFirstNameNodeDelegationStrategy();
                return(firstNameNodeValStrategy.IsValidFirstNameNode(node.AsFirstName(), binding, opDelStrategy));
            }

            case NodeKind.UnaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var unaryopNode = node.AsUnaryOpLit();
                IOpDelegationStrategy unaryOpNodeDelegationStrategy = _function.GetOpDelegationStrategy(unaryopNode.Op);
                return(unaryOpNodeDelegationStrategy.IsSupportedOpNode(unaryopNode, metadata, binding));
            }

            case NodeKind.BinaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var binaryOpNode = node.AsBinaryOp().VerifyValue();
                opDelStrategy = _function.GetOpDelegationStrategy(binaryOpNode.Op, binaryOpNode);

                var binaryOpDelStrategy = (opDelStrategy as BinaryOpDelegationStrategy).VerifyValue();
                Contracts.Assert(binaryOpNode.Op == binaryOpDelStrategy.Op);

                if (!opDelStrategy.IsSupportedOpNode(node, metadata, binding))
                {
                    SuggestDelegationHint(binaryOpNode, binding);
                    return(false);
                }

                break;
            }

            default:
            {
                var kind = node.Kind;
                if (kind != NodeKind.BoolLit && kind != NodeKind.StrLit && kind != NodeKind.NumLit)
                {
                    var telemetryMessage = string.Format("NodeKind {0} unsupported.", kind);
                    SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
                    return(false);
                }

                break;
            }
            }

            return(true);
        }
コード例 #17
0
ファイル: IsBlank.cs プロジェクト: jgrisham/Power-Fx
        public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (binding.ErrorContainer.HasErrors(callNode))
            {
                return(false);
            }

            if (!CheckArgsCount(callNode, binding))
            {
                return(false);
            }

            TexlNode[] args       = callNode.Args.Children.VerifyValue();
            var        opStrategy = GetOpDelegationStrategy(BinaryOp.Equal, null);

            if (binding.IsFullRecordRowScopeAccess(args[0]))
            {
                return(GetDottedNameNodeDelegationStrategy().IsValidDottedNameNode(args[0] as DottedNameNode, binding, metadata, opStrategy));
            }

            FirstNameNode node = args[0] as FirstNameNode;

            if (node == null)
            {
                var message = string.Format("Arg1 is not a firstname node, instead it is {0}", args[0].Kind);
                AddSuggestionMessageToTelemetry(message, args[0], binding);
                return(false);
            }

            if (!binding.IsRowScope(node))
            {
                return(false);
            }

            var firstNameNodeValidationStrategy = GetFirstNameNodeDelegationStrategy();

            return(firstNameNodeValidationStrategy.IsValidFirstNameNode(node, binding, opStrategy));
        }
コード例 #18
0
        public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (binding.ErrorContainer.HasErrors(callNode) ||
                !CheckArgsCount(callNode, binding) ||
                !binding.IsRowScope(callNode))
            {
                return(false);
            }

            TexlNode[] args    = callNode.Args.Children.VerifyValue();
            NodeKind   argKind = args[0].VerifyValue().Kind;

            var opStrategy        = GetOpDelegationStrategy(UnaryOp.Not);
            var firstNameStrategy = GetFirstNameNodeDelegationStrategy();
            var dottedStrategy    = GetDottedNameNodeDelegationStrategy();
            var cNodeStrategy     = GetCallNodeDelegationStrategy();

            switch (argKind)
            {
            case NodeKind.FirstName:
                return(firstNameStrategy.IsValidFirstNameNode(args[0].AsFirstName(), binding, opStrategy));

            case NodeKind.Call:
            {
                if (!opStrategy.IsOpSupportedByTable(metadata, callNode, binding))
                {
                    return(false);
                }

                return(cNodeStrategy.IsValidCallNode(args[0].AsCall(), binding, metadata));
            }

            case NodeKind.BinaryOp:
            {
                if (!opStrategy.IsOpSupportedByTable(metadata, callNode, binding))
                {
                    return(false);
                }

                BinaryOpNode          opNode = args[0].AsBinaryOp();
                IOpDelegationStrategy binaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op, opNode);
                return(binaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, metadata, binding));
            }

            case NodeKind.UnaryOp:
            {
                if (!opStrategy.IsOpSupportedByTable(metadata, callNode, binding))
                {
                    return(false);
                }

                UnaryOpNode opNode = args[0].AsUnaryOpLit();
                var         unaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op);
                return(unaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, metadata, binding));
            }

            case NodeKind.DottedName:
                return(dottedStrategy.IsValidDottedNameNode(args[0].AsDottedName(), binding, metadata, opStrategy));

            default:
                return(argKind == NodeKind.BoolLit);
            }
        }
コード例 #19
0
        public virtual bool IsSupportedOpNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);

            BinaryOpNode binaryOpNode = node.AsBinaryOp();

            if (binaryOpNode == null)
            {
                return(false);
            }

            IOpDelegationStrategy opDelStrategy = _function.GetOpDelegationStrategy(binaryOpNode.Op, binaryOpNode);
            var binaryOpDelStrategy             = (opDelStrategy as BinaryOpDelegationStrategy).VerifyValue();

            Contracts.Assert(binaryOpNode.Op == binaryOpDelStrategy.Op);

            // Check if binaryOp is supported by datasource in the context of filter operation.
            // If this is not allowed then there is no point in checking lhs and rhs
            // It's only safe to do so if lhs and rhs is first/dotted name node as columns (FirstName/DottedName node) can have additional capabilities defined.
            if (!(binaryOpNode.Left is FirstNameNode || binaryOpNode.Left is DottedNameNode) &&
                !(binaryOpNode.Right is FirstNameNode || binaryOpNode.Right is DottedNameNode) &&
                !opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
            {
                var telemetryMessage = string.Format("{0} operator not supported at table level", binaryOpNode.Op.ToString());
                SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
                TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.BinaryOpNoSupported, node, binding, _function, DelegationTelemetryInfo.CreateBinaryOpNoSupportedInfoTelemetryInfo(binaryOpNode.Op));
                return(false);
            }

            if (!ODataFunctionMappings.BinaryOpToOperatorMap.Value.ContainsKey(binaryOpNode.Op))
            {
                SuggestDelegationHint(node, binding);
                return(false);
            }

            if (!IsSupportedNode(binaryOpNode.Left, metadata, binding, opDelStrategy, false))
            {
                SuggestDelegationHint(node, binding);
                return(false);
            }

            if (!IsSupportedNode(binaryOpNode.Right, metadata, binding, opDelStrategy, true))
            {
                SuggestDelegationHint(node, binding);
                return(false);
            }

            DType leftType  = binding.GetType(binaryOpNode.Left);
            DType rightType = binding.GetType(binaryOpNode.Right);

            if ((leftType.IsPolymorphic && rightType.IsRecord) || (leftType.IsRecord && rightType.IsPolymorphic))
            {
                return(true);
            }

            if (!DoCoercionCheck(binaryOpNode, metadata, binding))
            {
                SuggestDelegationHint(node, binding);
                return(false);
            }

            return(true);
        }
コード例 #20
0
ファイル: AsType.cs プロジェクト: jgrisham/Power-Fx
 public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
 {
     return(binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled && metadata.IsDelegationSupportedByTable(DelegationCapability.AsType));
 }
コード例 #21
0
        public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (FunctionDelegationCapability.Capabilities == DelegationCapability.None ||
                binding.ErrorContainer.HasErrors(callNode) ||
                !CheckArgsCount(callNode, binding) ||
                !binding.IsRowScope(callNode))
            {
                return(false);
            }

            TexlNode[] args    = callNode.Args.Children.VerifyValue();
            NodeKind   argKind = args[0].VerifyValue().Kind;

            switch (argKind)
            {
            case NodeKind.FirstName:
            {
                var firstNameStrategy = GetFirstNameNodeDelegationStrategy();
                return(firstNameStrategy.IsValidFirstNameNode(args[0].AsFirstName(), binding, null));
            }

            case NodeKind.Call:
            {
                if (!metadata.IsDelegationSupportedByTable(FunctionDelegationCapability))
                {
                    return(false);
                }

                var cNodeStrategy = GetCallNodeDelegationStrategy();
                return(cNodeStrategy.IsValidCallNode(args[0].AsCall(), binding, metadata));
            }

            case NodeKind.DottedName:
            {
                var dottedStrategy = GetDottedNameNodeDelegationStrategy();
                return(dottedStrategy.IsValidDottedNameNode(args[0].AsDottedName(), binding, metadata, null));
            }

            default:
                break;
            }

            return(false);
        }