Esempio n. 1
0
 public bool Equals(InSetOfValuesEventPropIndexed other)
 {
     if (ReferenceEquals(null, other))
     {
         return(false);
     }
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     return(Equals(other._resultEventAsName, _resultEventAsName) && Equals(other._resultEventProperty, _resultEventProperty));
 }
        private static FilterSpecParam HandleInSetNode(
            ExprInNode constituent,
            IDictionary<string, Pair<EventType, string>> arrayEventTypes,
            ExprEvaluatorContext exprEvaluatorContext,
            string statementName)

        {
            var left = constituent.ChildNodes[0];
            if (!(left is ExprFilterOptimizableNode))
            {
                return null;
            }

            var filterOptimizableNode = (ExprFilterOptimizableNode) left;
            var lookupable = filterOptimizableNode.FilterLookupable;
            var op = FilterOperator.IN_LIST_OF_VALUES;
            if (constituent.IsNotIn)
            {
                op = FilterOperator.NOT_IN_LIST_OF_VALUES;
            }

            var expectedNumberOfConstants = constituent.ChildNodes.Length - 1;
            IList<FilterSpecParamInValue> listofValues = new List<FilterSpecParamInValue>();
            foreach (var subNode in constituent.ChildNodes.Skip(1)) // ignore the first node as it's the identifier
            {
                if (ExprNodeUtility.IsConstantValueExpr(subNode))
                {
                    var constantNode = (ExprConstantNode) subNode;
                    var constant = constantNode.GetConstantValue(exprEvaluatorContext);
                    if (constant != null && !constant.GetType().IsArray)
                    {
                        var constantType = constant.GetType();
                        if (constantType.IsGenericCollection())
                            return null;
                        if (constantType.IsGenericDictionary())
                            return null;
                    }

                    var asArray = constant as Array;
                    if (asArray != null)
                    {
                        for (var i = 0; i < asArray.Length; i++)
                        {
                            var arrayElement = asArray.GetValue(i);
                            var arrayElementCoerced = HandleConstantsCoercion(lookupable, arrayElement);
                            listofValues.Add(new InSetOfValuesConstant(arrayElementCoerced));
                            if (i > 0)
                            {
                                expectedNumberOfConstants++;
                            }
                        }
                    }
                    else
                    {
                        constant = HandleConstantsCoercion(lookupable, constant);
                        listofValues.Add(new InSetOfValuesConstant(constant));
                    }
                }
                if (subNode is ExprContextPropertyNode)
                {
                    var contextPropertyNode = (ExprContextPropertyNode) subNode;
                    var returnType = contextPropertyNode.ReturnType;
                    if (contextPropertyNode.ReturnType.IsImplementsInterface(typeof (ICollection<>)) ||
                        contextPropertyNode.ReturnType.IsImplementsInterface(typeof (IDictionary<,>)))
                    {
                        return null;
                    }
                    if ((returnType != null) && (returnType.GetType().IsArray))
                    {
                        return null;
                    }
                    var coercer = GetNumberCoercer(
                        left.ExprEvaluator.ReturnType, contextPropertyNode.ReturnType, lookupable.Expression);
                    listofValues.Add(
                        new InSetOfValuesContextProp(
                            contextPropertyNode.PropertyName, contextPropertyNode.Getter, coercer));
                }
                if (subNode is ExprIdentNode)
                {
                    var identNodeInner = (ExprIdentNode) subNode;
                    if (identNodeInner.StreamId == 0)
                    {
                        break; // for same event evals use the boolean expression, via count compare failing below
                    }

                    var isMustCoerce = false;
                    var numericCoercionType = lookupable.ReturnType.GetBoxedType();
                    if (identNodeInner.ExprEvaluator.ReturnType != lookupable.ReturnType)
                    {
                        if (lookupable.ReturnType.IsNumeric())
                        {
                            if (!identNodeInner.ExprEvaluator.ReturnType.CanCoerce(lookupable.ReturnType))
                            {
                                ThrowConversionError(
                                    identNodeInner.ExprEvaluator.ReturnType, lookupable.ReturnType,
                                    lookupable.Expression);
                            }
                            isMustCoerce = true;
                        }
                        else
                        {
                            break; // assumed not compatible
                        }
                    }

                    FilterSpecParamInValue inValue;
                    var streamName = identNodeInner.ResolvedStreamName;
                    if (arrayEventTypes != null && !arrayEventTypes.IsEmpty() && arrayEventTypes.ContainsKey(streamName))
                    {
                        var indexAndProp = GetStreamIndex(identNodeInner.ResolvedPropertyName);
                        inValue = new InSetOfValuesEventPropIndexed(
                            identNodeInner.ResolvedStreamName, indexAndProp.First.Value,
                            indexAndProp.Second, isMustCoerce, numericCoercionType, statementName);
                    }
                    else
                    {
                        inValue = new InSetOfValuesEventProp(
                            identNodeInner.ResolvedStreamName, identNodeInner.ResolvedPropertyName, isMustCoerce,
                            numericCoercionType);
                    }

                    listofValues.Add(inValue);
                }
            }

            // Fallback if not all values in the in-node can be resolved to properties or constants
            if (listofValues.Count == expectedNumberOfConstants)
            {
                return new FilterSpecParamIn(lookupable, op, listofValues);
            }
            return null;
        }