コード例 #1
0
        public static CodegenExpression Codegen(
            EnumTakeWhileIndexEventsForge forge,
            EnumForgeCodegenParams args,
            CodegenMethodScope codegenMethodScope,
            CodegenClassScope codegenClassScope)
        {
            var indexTypeMember = codegenClassScope.AddDefaultFieldUnshared(
                true,
                typeof(ObjectArrayEventType),
                Cast(
                    typeof(ObjectArrayEventType),
                    EventTypeUtility.ResolveTypeCodegen(forge.indexEventType, EPStatementInitServicesConstants.REF)));

            var scope = new ExprForgeCodegenSymbol(false, null);
            var methodNode = codegenMethodScope
                .MakeChildWithScope(
                    typeof(FlexCollection),
                    typeof(EnumTakeWhileIndexEventsForgeEval),
                    scope,
                    codegenClassScope)
                .AddParam(EnumForgeCodegenNames.PARAMS);

            var innerValue = forge.innerExpression.EvaluateCodegen(
                typeof(bool?),
                methodNode,
                scope,
                codegenClassScope);
            var block = methodNode.Block
                .IfCondition(ExprDotMethod(EnumForgeCodegenNames.REF_ENUMCOLL, "IsEmpty"))
                .BlockReturn(EnumForgeCodegenNames.REF_ENUMCOLL)
                .DeclareVar<ObjectArrayEventBean>(
                    "indexEvent",
                    NewInstance<ObjectArrayEventBean>(NewArrayByLength(typeof(object), Constant(1)), indexTypeMember))
                .AssignArrayElement(
                    EnumForgeCodegenNames.REF_EPS,
                    Constant(forge.streamNumLambda + 1),
                    Ref("indexEvent"))
                .DeclareVar<object[]>("props", ExprDotName(Ref("indexEvent"), "Properties"));

            var blockSingle = block
                .IfCondition(EqualsIdentity(ExprDotName(EnumForgeCodegenNames.REF_ENUMCOLL, "Count"), Constant(1)))
                .DeclareVar<EventBean>(
                    "item",
                    Cast(
                        typeof(EventBean),
                        ExprDotMethodChain(EnumForgeCodegenNames.REF_ENUMCOLL).Add("First")))
                .AssignArrayElement("props", Constant(0), Constant(0))
                .AssignArrayElement(EnumForgeCodegenNames.REF_EPS, Constant(forge.streamNumLambda), Ref("item"));
            CodegenLegoBooleanExpression.CodegenReturnValueIfNotNullAndNotPass(
                blockSingle,
                forge.innerExpression.EvaluationType,
                innerValue,
                FlexEmpty());
            blockSingle.BlockReturn(FlexEvent(Ref("item")));

            block.DeclareVar<ArrayDeque<EventBean>>("result", NewInstance(typeof(ArrayDeque<EventBean>)))
                .DeclareVar<int>("count", Constant(-1));
            var forEach = block.ForEach(typeof(EventBean), "next", EnumForgeCodegenNames.REF_ENUMCOLL)
                .Increment("count")
                .AssignArrayElement("props", Constant(0), Ref("count"))
                .AssignArrayElement(EnumForgeCodegenNames.REF_EPS, Constant(forge.streamNumLambda), Ref("next"));
            CodegenLegoBooleanExpression.CodegenBreakIfNotNullAndNotPass(
                forEach,
                forge.innerExpression.EvaluationType,
                innerValue);
            forEach.Expression(ExprDotMethod(Ref("result"), "Add", Ref("next")));
            block.MethodReturn(FlexWrap(Ref("result")));
            return LocalMethod(methodNode, args.Eps, args.Enumcoll, args.IsNewData, args.ExprCtx);
        }
コード例 #2
0
ファイル: WrapperEventType.cs プロジェクト: lanicon/nesper
        public EventPropertyGetterIndexedSPI GetGetterIndexedSPI(string indexedProperty)
        {
            var undIndexed = ((EventTypeSPI) underlyingEventType).GetGetterIndexedSPI(indexedProperty);
            if (undIndexed != null) {
                return new WrapperGetterIndexed(undIndexed);
            }

            var decoIndexed = underlyingMapType.GetGetterIndexedSPI(indexedProperty);
            if (decoIndexed != null) {
                return new ProxyEventPropertyGetterIndexedSPI {
                    ProcGet = (
                        theEvent,
                        index) => {
                        if (!(theEvent is DecoratingEventBean)) {
                            throw new PropertyAccessException("Mismatched property getter to EventBean type");
                        }

                        var wrapperEvent = (DecoratingEventBean) theEvent;
                        var map = wrapperEvent.DecoratingProperties;
                        EventBean wrapped = eventBeanTypedEventFactory.AdapterForTypedMap(map, underlyingMapType);
                        return decoIndexed.Get(wrapped, index);
                    },

                    ProcEventBeanGetIndexedCodegen = (
                        codegenMethodScope,
                        codegenClassScope,
                        beanExpression,
                        key) => {
                        var factory =
                            codegenClassScope.AddOrGetDefaultFieldSharable(EventBeanTypedEventFactoryCodegenField.INSTANCE);
                        var eventType = codegenClassScope.AddDefaultFieldUnshared<EventType>(
                            true,
                            EventTypeUtility.ResolveTypeCodegen(
                                underlyingEventType,
                                EPStatementInitServicesConstants.REF));
                        var method = codegenMethodScope
                            .MakeChild(typeof(object), typeof(WrapperEventType), codegenClassScope)
                            .AddParam(typeof(EventBean), "theEvent")
                            .AddParam(typeof(int), "index")
                            .Block
                            .DeclareVar<DecoratingEventBean>(
                                "wrapperEvent",
                                Cast(typeof(DecoratingEventBean), Ref("theEvent")))
                            .DeclareVar<IDictionary<object, object>>(
                                "map",
                                ExprDotName(Ref("wrapperEvent"), "DecoratingProperties"))
                            .DeclareVar<EventBean>(
                                "wrapped",
                                ExprDotMethod(factory, "AdapterForTypedMap", Ref("map"), eventType))
                            .MethodReturn(
                                decoIndexed.EventBeanGetIndexedCodegen(
                                    codegenMethodScope,
                                    codegenClassScope,
                                    Ref("wrapped"),
                                    Ref("index")));
                        return LocalMethodBuild(method).Pass(beanExpression).Pass(key).Call();
                    }
                };
            }

            return null;
        }
コード例 #3
0
        public static FilterValueSetParam[][] GetAddendumFilters(
            object keyValue,
            FilterSpecCompiled filtersSpec,
            ContextDetailPartitioned segmentedSpec,
            StatementSpecCompiled optionalStatementSpecCompiled)
        {
            // determine whether create-named-window
            var isCreateWindow = optionalStatementSpecCompiled != null &&
                                 optionalStatementSpecCompiled.CreateWindowDesc != null;
            ContextDetailPartitionItem foundPartition = null;

            if (!isCreateWindow)
            {
                foreach (var partitionItem in segmentedSpec.Items)
                {
                    var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(
                        filtersSpec.FilterForEventType, partitionItem.FilterSpecCompiled.FilterForEventType);
                    if (typeOrSubtype)
                    {
                        foundPartition = partitionItem;
                    }
                }
            }
            else
            {
                var declaredAsName = optionalStatementSpecCompiled.CreateWindowDesc.AsEventTypeName;
                if (declaredAsName == null)
                {
                    return(null);
                }
                foreach (var partitionItem in segmentedSpec.Items)
                {
                    if (partitionItem.FilterSpecCompiled.FilterForEventType.Name.Equals(declaredAsName))
                    {
                        foundPartition = partitionItem;
                        break;
                    }
                }
            }

            if (foundPartition == null)
            {
                return(null);
            }

            var addendumFilters = new List <FilterValueSetParam>(foundPartition.PropertyNames.Count);

            if (foundPartition.PropertyNames.Count == 1)
            {
                var propertyName = foundPartition.PropertyNames[0];
                var getter       = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(propertyName);
                var resultType   = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(propertyName);
                var lookupable   = new FilterSpecLookupable(propertyName, getter, resultType, false);
                var filter       = GetFilterMayEqualOrNull(lookupable, keyValue);
                addendumFilters.Add(filter);
            }
            else
            {
                var keys = ((MultiKeyUntyped)keyValue).Keys;
                for (var i = 0; i < foundPartition.PropertyNames.Count; i++)
                {
                    var partitionPropertyName = foundPartition.PropertyNames[i];
                    var getter     = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(partitionPropertyName);
                    var resultType = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(partitionPropertyName);
                    var lookupable = new FilterSpecLookupable(partitionPropertyName, getter, resultType, false);
                    var filter     = GetFilterMayEqualOrNull(lookupable, keys[i]);
                    addendumFilters.Add(filter);
                }
            }

            var addendum = new FilterValueSetParam[1][];

            addendum[0] = addendumFilters.ToArray();

            var partitionFilters = foundPartition.ParametersCompiled;

            if (partitionFilters != null)
            {
                addendum = ContextControllerAddendumUtil.AddAddendum(partitionFilters, addendum[0]);
            }

            return(addendum);
        }
コード例 #4
0
        private CodegenExpression MakeEventToPublic(
            CodegenMethodScope parent,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            var method = parent.MakeChild(typeof(TableMetadataInternalEventToPublic), GetType(), classScope);
            var factory = classScope.AddOrGetDefaultFieldSharable(EventBeanTypedEventFactoryCodegenField.INSTANCE);
            var eventType = classScope.AddDefaultFieldUnshared(
                true,
                typeof(EventType),
                EventTypeUtility.ResolveTypeCodegen(_plan.PublicEventType, EPStatementInitServicesConstants.REF));

            CodegenExpressionLambda convertToUnd = new CodegenExpressionLambda(method.Block)
                .WithParams(new CodegenNamedParam(typeof(EventBean), "@event"))
                .WithParams(PARAMS);

            convertToUnd.Block
                .DeclareVar<object[]>(
                    "props",
                    ExprDotName(Cast(typeof(ObjectArrayBackedEventBean), Ref("@event")), "Properties"))
                .DeclareVar<object[]>(
                    "data",
                    NewArrayByLength(typeof(object), Constant(_plan.PublicEventType.PropertyNames.Length)));
            foreach (TableMetadataColumnPairPlainCol plain in _plan.ColsPlain) {
                convertToUnd.Block.AssignArrayElement(
                    Ref("data"),
                    Constant(plain.Dest),
                    ArrayAtIndex(Ref("props"), Constant(plain.Source)));
            }

            if (_plan.ColsAggMethod.Length > 0 || _plan.ColsAccess.Length > 0) {
                convertToUnd.Block.DeclareVar<AggregationRow>(
                    "row",
                    Cast(typeof(AggregationRow), ArrayAtIndex(Ref("props"), Constant(0))));
                var count = 0;

                foreach (TableMetadataColumnPairAggMethod aggMethod in _plan.ColsAggMethod) {
                    // Code: data[method.getDest()] = row.getMethods()[count++].getValue();
                    convertToUnd.Block.DebugStack();
                    convertToUnd.Block.AssignArrayElement(
                        Ref("data"),
                        Constant(aggMethod.Dest),
                        ExprDotMethod(
                            Ref("row"),
                            "GetValue",
                            Constant(count),
                            REF_EPS,
                            REF_ISNEWDATA,
                            REF_EXPREVALCONTEXT));
                    count++;
                }

                foreach (TableMetadataColumnPairAggAccess aggAccess in _plan.ColsAccess) {
                    // Code: data[method.getDest()] = row.getMethods()[count++].getValue();
                    convertToUnd.Block.DebugStack();
                    convertToUnd.Block.AssignArrayElement(
                        Ref("data"),
                        Constant(aggAccess.Dest),
                        ExprDotMethod(
                            Ref("row"),
                            "GetValue",
                            Constant(count),
                            REF_EPS,
                            REF_ISNEWDATA,
                            REF_EXPREVALCONTEXT));
                    count++;
                }
            }

            convertToUnd.Block.BlockReturn(Ref("data"));

            method.Block.DeclareVar<ProxyTableMetadataInternalEventToPublic.ConvertToUndFunc>(
                "convertToUndFunc",
                convertToUnd);

            CodegenExpressionLambda convert = new CodegenExpressionLambda(method.Block)
                .WithParams(new CodegenNamedParam(typeof(EventBean), "@event"))
                .WithParams(PARAMS);

            convert.Block
                .DeclareVar<object[]>(
                    "data",
                    ExprDotMethod(
                        Ref("convertToUndFunc"),
                        "Invoke",
                        Ref("@event"),
                        REF_EPS,
                        REF_ISNEWDATA,
                        REF_EXPREVALCONTEXT))
                .BlockReturn(ExprDotMethod(factory, "AdapterForTypedObjectArray", Ref("data"), eventType));

            method.Block.DeclareVar<ProxyTableMetadataInternalEventToPublic.ConvertFunc>(
                "convertFunc",
                convert);

            method.Block.MethodReturn(
                NewInstance<ProxyTableMetadataInternalEventToPublic>(
                    Ref("convertFunc"),
                    Ref("convertToUndFunc")));

            //method.Block.MethodReturn(clazz);
            return LocalMethod(method);
        }
コード例 #5
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            // check for plannable methods: these are validated according to different rules
            var appDotMethod = GetAppDotMethod(validationContext.IsFilterExpression);
            if (appDotMethod != null) {
                return appDotMethod;
            }

            // validate all parameters
            ExprNodeUtilityValidate.Validate(ExprNodeOrigin.DOTNODEPARAMETER, ChainSpec, validationContext);

            // determine if there are enumeration method expressions in the chain
            var hasEnumerationMethod = false;
            foreach (var chain in ChainSpec) {
                if (EnumMethodEnumExtensions.IsEnumerationMethod(chain.Name)) {
                    hasEnumerationMethod = true;
                    break;
                }
            }

            // determine if there is an implied binding, replace first chain element with evaluation node if there is
            if (validationContext.StreamTypeService.HasTableTypes &&
                validationContext.TableCompileTimeResolver != null &&
                ChainSpec.Count > 1 &&
                ChainSpec[0].IsProperty) {
                var tableNode = TableCompileTimeUtil.GetTableNodeChainable(
                    validationContext.StreamTypeService,
                    ChainSpec,
                    validationContext.ImportService,
                    validationContext.TableCompileTimeResolver);
                if (tableNode != null) {
                    var node = ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.DOTNODE,
                        tableNode.First,
                        validationContext);
                    if (tableNode.Second.IsEmpty()) {
                        return node;
                    }

                    ChainSpec.Clear();
                    ChainSpec.AddAll(tableNode.Second);
                    AddChildNode(node);
                }
            }

            // The root node expression may provide the input value:
            //   Such as "window(*).doIt(...)" or "(select * from Window).doIt()" or "prevwindow(sb).doIt(...)", in which case the expression to act on is a child expression
            //
            var streamTypeService = validationContext.StreamTypeService;
            if (ChildNodes.Length != 0) {
                // the root expression is the first child node
                var rootNode = ChildNodes[0];

                // the root expression may also provide a lambda-function input (Iterator<EventBean>)
                // Determine collection-type and evaluator if any for root node
                var enumSrc = ExprDotNodeUtility.GetEnumerationSource(
                    rootNode,
                    validationContext.StreamTypeService,
                    hasEnumerationMethod,
                    validationContext.IsDisablePropertyExpressionEventCollCache,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);

                EPType typeInfoX;
                if (enumSrc.ReturnType == null) {
                    typeInfoX = EPTypeHelper.SingleValue(
                        rootNode.Forge.EvaluationType); // not a collection type, treat as scalar
                }
                else {
                    typeInfoX = enumSrc.ReturnType;
                }

                var evalsX = ExprDotNodeUtility.GetChainEvaluators(
                    enumSrc.StreamOfProviderIfApplicable,
                    typeInfoX,
                    ChainSpec,
                    validationContext,
                    isDuckTyping,
                    new ExprDotNodeFilterAnalyzerInputExpr());
                forge = new ExprDotNodeForgeRootChild(
                    this,
                    null,
                    null,
                    null,
                    hasEnumerationMethod,
                    rootNode.Forge,
                    enumSrc.Enumeration,
                    typeInfoX,
                    evalsX.Chain,
                    evalsX.ChainWithUnpack,
                    false);
                return null;
            }

            // No root node, and this is a 1-element chain i.e. "something(param,...)".
            // Plug-in single-row methods are not handled here.
            // Plug-in aggregation methods are not handled here.
            if (ChainSpec.Count == 1) {
                var spec = ChainSpec[0];
                if (spec.Parameters.IsEmpty()) {
                    throw HandleNotFound(spec.Name);
                }

                // single-parameter can resolve to a property
                Pair<PropertyResolutionDescriptor, string> propertyInfoPairX = null;
                try {
                    propertyInfoPairX = ExprIdentNodeUtil.GetTypeFromStream(
                        streamTypeService,
                        spec.Name,
                        streamTypeService.HasPropertyAgnosticType,
                        false,
                        validationContext.TableCompileTimeResolver);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }

                // if not a property then try built-in single-row non-grammar functions
                if (propertyInfoPairX == null &&
                    spec.Name.ToLowerInvariant()
                        .Equals(ImportServiceCompileTime.EXT_SINGLEROW_FUNCTION_TRANSPOSE)) {
                    if (spec.Parameters.Count != 1) {
                        throw new ExprValidationException(
                            "The " +
                            ImportServiceCompileTime.EXT_SINGLEROW_FUNCTION_TRANSPOSE +
                            " function requires a single parameter expression");
                    }

                    forge = new ExprDotNodeForgeTransposeAsStream(this, ChainSpec[0].Parameters[0].Forge);
                }
                else if (spec.Parameters.Count != 1) {
                    throw HandleNotFound(spec.Name);
                }
                else {
                    if (propertyInfoPairX == null) {
                        throw new ExprValidationException(
                            "Unknown single-row function, aggregation function or mapped or indexed property named '" +
                            spec.Name +
                            "' could not be resolved");
                    }

                    forge = GetPropertyPairEvaluator(spec.Parameters[0].Forge, propertyInfoPairX, validationContext);
                }

                return null;
            }

            // handle the case where the first chain spec element is a stream name.
            ExprValidationException prefixedStreamNumException = null;
            var prefixedStreamNumber = PrefixedStreamName(ChainSpec, validationContext.StreamTypeService);
            if (prefixedStreamNumber != -1) {
                var specAfterStreamName = ChainSpec[1];

                // Attempt to resolve as property
                Pair<PropertyResolutionDescriptor, string> propertyInfoPairX = null;
                try {
                    var propName = ChainSpec[0].Name + "." + specAfterStreamName.Name;
                    propertyInfoPairX = ExprIdentNodeUtil.GetTypeFromStream(
                        streamTypeService,
                        propName,
                        streamTypeService.HasPropertyAgnosticType,
                        false,
                        validationContext.TableCompileTimeResolver);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }

                if (propertyInfoPairX != null) {
                    if (specAfterStreamName.Parameters.Count != 1) {
                        throw HandleNotFound(specAfterStreamName.Name);
                    }

                    forge = GetPropertyPairEvaluator(
                        specAfterStreamName.Parameters[0].Forge,
                        propertyInfoPairX,
                        validationContext);
                    return null;
                }

                // Attempt to resolve as event-underlying object instance method
                var eventType = validationContext.StreamTypeService.EventTypes[prefixedStreamNumber];
                var type = eventType.UnderlyingType;

                IList<ExprChainedSpec> remainderChain = new List<ExprChainedSpec>(ChainSpec);
                remainderChain.RemoveAt(0);

                ExprValidationException methodEx = null;
                ExprDotForge[] underlyingMethodChain = null;
                try {
                    var typeInfoX = EPTypeHelper.SingleValue(type);
                    if (validationContext.TableCompileTimeResolver.ResolveTableFromEventType(eventType) != null) {
                        typeInfoX = new ClassEPType(typeof(object[]));
                    }

                    underlyingMethodChain = ExprDotNodeUtility.GetChainEvaluators(
                            prefixedStreamNumber,
                            typeInfoX,
                            remainderChain,
                            validationContext,
                            false,
                            new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber))
                        .ChainWithUnpack;
                }
                catch (ExprValidationException ex) {
                    methodEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

                ExprDotForge[] eventTypeMethodChain = null;
                ExprValidationException enumDatetimeEx = null;
                FilterExprAnalyzerAffector filterExprAnalyzerAffector = null;
                try {
                    var typeInfoX = EPTypeHelper.SingleEvent(eventType);
                    var chain = ExprDotNodeUtility.GetChainEvaluators(
                        prefixedStreamNumber,
                        typeInfoX,
                        remainderChain,
                        validationContext,
                        false,
                        new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber));
                    eventTypeMethodChain = chain.ChainWithUnpack;
                    filterExprAnalyzerAffector = chain.FilterAnalyzerDesc;
                }
                catch (ExprValidationException ex) {
                    enumDatetimeEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

                if (underlyingMethodChain != null) {
                    forge = new ExprDotNodeForgeStream(
                        this,
                        filterExprAnalyzerAffector,
                        prefixedStreamNumber,
                        eventType,
                        underlyingMethodChain,
                        true);
                }
                else if (eventTypeMethodChain != null) {
                    forge = new ExprDotNodeForgeStream(
                        this,
                        filterExprAnalyzerAffector,
                        prefixedStreamNumber,
                        eventType,
                        eventTypeMethodChain,
                        false);
                }

                if (forge != null) {
                    return null;
                }

                if (ExprDotNodeUtility.IsDatetimeOrEnumMethod(remainderChain[0].Name)) {
                    prefixedStreamNumException = enumDatetimeEx;
                }
                else {
                    prefixedStreamNumException = new ExprValidationException(
                        "Failed to solve '" +
                        remainderChain[0].Name +
                        "' to either an date-time or enumeration method, an event property or a method on the event underlying object: " +
                        methodEx.Message,
                        methodEx);
                }
            }

            // There no root node, in this case the classname or property name is provided as part of the chain.
            // Such as "MyClass.myStaticLib(...)" or "mycollectionproperty.doIt(...)"
            //
            IList<ExprChainedSpec> modifiedChain = new List<ExprChainedSpec>(ChainSpec);
            var firstItem = modifiedChain.DeleteAt(0);

            Pair<PropertyResolutionDescriptor, string> propertyInfoPair = null;
            try {
                propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(
                    streamTypeService,
                    firstItem.Name,
                    streamTypeService.HasPropertyAgnosticType,
                    true,
                    validationContext.TableCompileTimeResolver);
            }
            catch (ExprValidationPropertyException) {
                // not a property
            }

            // If property then treat it as such
            if (propertyInfoPair != null) {
                var propertyName = propertyInfoPair.First.PropertyName;
                var streamId = propertyInfoPair.First.StreamNum;
                var streamType = streamTypeService.EventTypes[streamId];
                EPType typeInfoX;
                ExprEnumerationForge enumerationForge = null;
                EPType inputType;
                ExprForge rootNodeForge = null;
                EventPropertyGetterSPI getter;

                if (firstItem.Parameters.IsEmpty()) {
                    getter = ((EventTypeSPI) streamType).GetGetterSPI(propertyInfoPair.First.PropertyName);

                    var propertyEval =
                        ExprDotNodeUtility.GetPropertyEnumerationSource(
                            propertyInfoPair.First.PropertyName,
                            streamId,
                            streamType,
                            hasEnumerationMethod,
                            validationContext.IsDisablePropertyExpressionEventCollCache);
                    typeInfoX = propertyEval.ReturnType;
                    enumerationForge = propertyEval.Enumeration;
                    inputType = propertyEval.ReturnType;
                    rootNodeForge = new PropertyDotNonLambdaForge(
                        streamId,
                        getter,
                        propertyInfoPair.First.PropertyType.GetBoxedType());
                }
                else {
                    // property with parameter - mapped or indexed property
                    var desc = EventTypeUtility.GetNestablePropertyDescriptor(
                        streamTypeService.EventTypes[propertyInfoPair.First.StreamNum],
                        firstItem.Name);
                    if (firstItem.Parameters.Count > 1) {
                        throw new ExprValidationException(
                            "Property '" + firstItem.Name + "' may not be accessed passing 2 or more parameters");
                    }

                    var paramEval = firstItem.Parameters[0].Forge;
                    typeInfoX = EPTypeHelper.SingleValue(desc.PropertyComponentType);
                    inputType = typeInfoX;
                    getter = null;
                    if (desc.IsMapped) {
                        if (paramEval.EvaluationType != typeof(string)) {
                            throw new ExprValidationException(
                                "Parameter expression to mapped property '" +
                                propertyName +
                                "' is expected to return a string-type value but returns " +
                                paramEval.EvaluationType.CleanName());
                        }

                        var mappedGetter =
                            ((EventTypeSPI) propertyInfoPair.First.StreamEventType).GetGetterMappedSPI(
                                propertyInfoPair.First.PropertyName);
                        if (mappedGetter == null) {
                            throw new ExprValidationException(
                                "Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }

                        rootNodeForge = new PropertyDotNonLambdaMappedForge(
                            streamId,
                            mappedGetter,
                            paramEval,
                            desc.PropertyComponentType);
                    }

                    if (desc.IsIndexed) {
                        if (paramEval.EvaluationType.GetBoxedType() != typeof(int?)) {
                            throw new ExprValidationException(
                                "Parameter expression to mapped property '" +
                                propertyName +
                                "' is expected to return a Integer-type value but returns " +
                                paramEval.EvaluationType.CleanName());
                        }

                        var indexedGetter =
                            ((EventTypeSPI) propertyInfoPair.First.StreamEventType).GetGetterIndexedSPI(
                                propertyInfoPair.First.PropertyName);
                        if (indexedGetter == null) {
                            throw new ExprValidationException(
                                "Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }

                        rootNodeForge = new PropertyDotNonLambdaIndexedForge(
                            streamId,
                            indexedGetter,
                            paramEval,
                            desc.PropertyComponentType);
                    }
                }

                if (typeInfoX == null) {
                    throw new ExprValidationException(
                        "Property '" + propertyName + "' is not a mapped or indexed property");
                }

                // try to build chain based on the input (non-fragment)
                ExprDotNodeRealizedChain evalsX;
                var filterAnalyzerInputProp = new ExprDotNodeFilterAnalyzerInputProp(
                    propertyInfoPair.First.StreamNum,
                    propertyInfoPair.First.PropertyName);
                var rootIsEventBean = false;
                try {
                    evalsX = ExprDotNodeUtility.GetChainEvaluators(
                        streamId,
                        inputType,
                        modifiedChain,
                        validationContext,
                        isDuckTyping,
                        filterAnalyzerInputProp);
                }
                catch (ExprValidationException) {
                    // try building the chain based on the fragment event type (i.e. A.after(B) based on A-configured start time where A is a fragment)
                    var fragment = propertyInfoPair.First.FragmentEventType;
                    if (fragment == null) {
                        throw;
                    }

                    EPType fragmentTypeInfo;
                    if (fragment.IsIndexed) {
                        fragmentTypeInfo = EPTypeHelper.CollectionOfEvents(fragment.FragmentType);
                    }
                    else {
                        fragmentTypeInfo = EPTypeHelper.SingleEvent(fragment.FragmentType);
                    }

                    rootIsEventBean = true;
                    evalsX = ExprDotNodeUtility.GetChainEvaluators(
                        propertyInfoPair.First.StreamNum,
                        fragmentTypeInfo,
                        modifiedChain,
                        validationContext,
                        isDuckTyping,
                        filterAnalyzerInputProp);
                    rootNodeForge = new PropertyDotNonLambdaFragmentForge(streamId, getter);
                }

                var filterExprAnalyzerAffector = evalsX.FilterAnalyzerDesc;
                var streamNumReferenced = propertyInfoPair.First.StreamNum;
                var rootPropertyName = propertyInfoPair.First.PropertyName;
                forge = new ExprDotNodeForgeRootChild(
                    this,
                    filterExprAnalyzerAffector,
                    streamNumReferenced,
                    rootPropertyName,
                    hasEnumerationMethod,
                    rootNodeForge,
                    enumerationForge,
                    inputType,
                    evalsX.Chain,
                    evalsX.ChainWithUnpack,
                    !rootIsEventBean);
                return null;
            }

            // If variable then resolve as such
            var variable = validationContext.VariableCompileTimeResolver.Resolve(firstItem.Name);
            if (variable != null) {
                if (variable.OptionalContextName != null) {
                    throw new ExprValidationException(
                        "Method invocation on context-specific variable is not supported");
                }

                EPType typeInfoX;
                ExprDotStaticMethodWrap wrap;
                if (variable.Type.IsArray) {
                    typeInfoX = EPTypeHelper.CollectionOfSingleValue(
                        variable.Type.GetElementType(),
                        variable.Type);
                    wrap = new ExprDotStaticMethodWrapArrayScalar(variable.VariableName, variable.Type);
                }
                else if (variable.EventType != null) {
                    typeInfoX = EPTypeHelper.SingleEvent(variable.EventType);
                    wrap = null;
                }
                else {
                    typeInfoX = EPTypeHelper.SingleValue(variable.Type);
                    wrap = null;
                }

                var evalsX = ExprDotNodeUtility.GetChainEvaluators(
                    null,
                    typeInfoX,
                    modifiedChain,
                    validationContext,
                    false,
                    new ExprDotNodeFilterAnalyzerInputStatic());
                forge = new ExprDotNodeForgeVariable(this, variable, wrap, evalsX.ChainWithUnpack);
                return null;
            }

            // try resolve as enumeration class with value
            var enumconstant = ImportCompileTimeUtil.ResolveIdentAsEnumConst(
                firstItem.Name,
                validationContext.ImportService,
                false);
            if (enumconstant != null) {
                // try resolve method
                var methodSpec = modifiedChain[0];
                var enumvalue = firstItem.Name;
                ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler {
                    ProcHandle = ex => {
                        return new ExprValidationException(
                            "Failed to resolve method '" +
                            methodSpec.Name +
                            "' on enumeration value '" +
                            enumvalue +
                            "': " +
                            ex.Message);
                    }
                };
                var wildcardType = validationContext.StreamTypeService.EventTypes.Length != 1
                    ? null
                    : validationContext.StreamTypeService.EventTypes[0];
                var methodDesc = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
                    enumconstant.GetType().Name,
                    enumconstant.GetType(),
                    methodSpec.Name,
                    methodSpec.Parameters,
                    wildcardType != null,
                    wildcardType,
                    handler,
                    methodSpec.Name,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);

                // method resolved, hook up
                modifiedChain.RemoveAt(0); // we identified this piece
                var optionalLambdaWrapX = ExprDotStaticMethodWrapFactory.Make(
                    methodDesc.ReflectionMethod,
                    modifiedChain,
                    null,
                    validationContext);
                var typeInfoX = optionalLambdaWrapX != null
                    ? optionalLambdaWrapX.TypeInfo
                    : EPTypeHelper.SingleValue(methodDesc.ReflectionMethod.ReturnType);

                var evalsX = ExprDotNodeUtility.GetChainEvaluators(
                    null,
                    typeInfoX,
                    modifiedChain,
                    validationContext,
                    false,
                    new ExprDotNodeFilterAnalyzerInputStatic());
                forge = new ExprDotNodeForgeStaticMethod(
                    this,
                    false,
                    firstItem.Name,
                    methodDesc.ReflectionMethod,
                    methodDesc.ChildForges,
                    false,
                    evalsX.ChainWithUnpack,
                    optionalLambdaWrapX,
                    false,
                    enumconstant,
                    validationContext.StatementName);
                return null;
            }

            // if prefixed by a stream name, we are giving up
            if (prefixedStreamNumException != null) {
                throw prefixedStreamNumException;
            }

            // If class then resolve as class
            var secondItem = modifiedChain.DeleteAt(0);

            var allowWildcard = validationContext.StreamTypeService.EventTypes.Length == 1;
            EventType streamZeroType = null;
            if (validationContext.StreamTypeService.EventTypes.Length > 0) {
                streamZeroType = validationContext.StreamTypeService.EventTypes[0];
            }

            var method = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
                firstItem.Name,
                null,
                secondItem.Name,
                secondItem.Parameters,
                allowWildcard,
                streamZeroType,
                new ExprNodeUtilResolveExceptionHandlerDefault(firstItem.Name + "." + secondItem.Name, false),
                secondItem.Name,
                validationContext.StatementRawInfo,
                validationContext.StatementCompileTimeService);

            var isConstantParameters = method.IsAllConstants && isUDFCache;
            var isReturnsConstantResult = isConstantParameters && modifiedChain.IsEmpty();

            // this may return a pair of null if there is no lambda or the result cannot be wrapped for lambda-function use
            var optionalLambdaWrap = ExprDotStaticMethodWrapFactory.Make(
                method.ReflectionMethod,
                modifiedChain,
                null,
                validationContext);
            var typeInfo = optionalLambdaWrap != null
                ? optionalLambdaWrap.TypeInfo
                : EPTypeHelper.SingleValue(method.ReflectionMethod.ReturnType);

            var evals = ExprDotNodeUtility.GetChainEvaluators(
                null,
                typeInfo,
                modifiedChain,
                validationContext,
                false,
                new ExprDotNodeFilterAnalyzerInputStatic());
            forge = new ExprDotNodeForgeStaticMethod(
                this,
                isReturnsConstantResult,
                firstItem.Name,
                method.ReflectionMethod,
                method.ChildForges,
                isConstantParameters,
                evals.ChainWithUnpack,
                optionalLambdaWrap,
                false,
                null,
                validationContext.StatementName);

            return null;
        }
コード例 #6
0
ファイル: ExprDotNode.cs プロジェクト: ikvm/nesper
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            // validate all parameters
            ExprNodeUtility.Validate(ExprNodeOrigin.DOTNODEPARAMETER, _chainSpec, validationContext);

            // determine if there are enumeration method expressions in the chain
            bool hasEnumerationMethod = false;

            foreach (ExprChainedSpec chain in _chainSpec)
            {
                if (EnumMethodEnumExtensions.IsEnumerationMethod(chain.Name))
                {
                    hasEnumerationMethod = true;
                    break;
                }
            }

            // determine if there is an implied binding, replace first chain element with evaluation node if there is
            if (validationContext.StreamTypeService.HasTableTypes &&
                validationContext.TableService != null &&
                _chainSpec.Count > 1 && _chainSpec[0].IsProperty)
            {
                Pair <ExprNode, IList <ExprChainedSpec> > tableNode = validationContext.TableService.GetTableNodeChainable(validationContext.StreamTypeService, _chainSpec, validationContext.MethodResolutionService.EngineImportService);
                if (tableNode != null)
                {
                    ExprNode node = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.DOTNODE, tableNode.First, validationContext);
                    if (tableNode.Second.IsEmpty())
                    {
                        return(node);
                    }
                    _chainSpec.Clear();
                    _chainSpec.AddAll(tableNode.Second);
                    AddChildNode(node);
                }
            }

            // The root node expression may provide the input value:
            //   Such as "window(*).doIt(...)" or "(select * from Window).doIt()" or "prevwindow(sb).doIt(...)", in which case the expression to act on is a child expression
            //
            StreamTypeService streamTypeService = validationContext.StreamTypeService;

            if (ChildNodes.Length != 0)
            {
                // the root expression is the first child node
                ExprNode      rootNode          = ChildNodes[0];
                ExprEvaluator rootNodeEvaluator = rootNode.ExprEvaluator;

                // the root expression may also provide a lambda-function input (GetEnumerator<EventBean>)
                // Determine collection-type and evaluator if any for root node
                ExprDotEnumerationSource enumSrc = ExprDotNodeUtility.GetEnumerationSource(rootNode, validationContext.StreamTypeService, validationContext.EventAdapterService, validationContext.StatementId, hasEnumerationMethod, validationContext.IsDisablePropertyExpressionEventCollCache);

                EPType typeInfo;
                if (enumSrc.ReturnType == null)
                {
                    typeInfo = EPTypeHelper.SingleValue(rootNodeEvaluator.ReturnType);        // not a collection type, treat as scalar
                }
                else
                {
                    typeInfo = enumSrc.ReturnType;
                }

                ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(enumSrc.StreamOfProviderIfApplicable, typeInfo, _chainSpec, validationContext, _isDuckTyping, new ExprDotNodeFilterAnalyzerInputExpr());
                _exprEvaluator = new ExprDotEvalRootChild(hasEnumerationMethod, this, rootNodeEvaluator, enumSrc.Enumeration, typeInfo, evals.Chain, evals.ChainWithUnpack, false);
                return(null);
            }

            // No root node, and this is a 1-element chain i.e. "something(param,...)".
            // Plug-in single-row methods are not handled here.
            // Plug-in aggregation methods are not handled here.
            if (_chainSpec.Count == 1)
            {
                ExprChainedSpec spec = _chainSpec[0];
                if (spec.Parameters.IsEmpty())
                {
                    throw HandleNotFound(spec.Name);
                }

                // single-parameter can resolve to a property
                Pair <PropertyResolutionDescriptor, string> propertyInfoPair = null;
                try {
                    propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, spec.Name, streamTypeService.HasPropertyAgnosticType, false);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }

                // if not a property then try built-in single-row non-grammar functions
                if (propertyInfoPair == null && string.Equals(spec.Name, EngineImportServiceConstants.EXT_SINGLEROW_FUNCTION_TRANSPOSE, StringComparison.OrdinalIgnoreCase))
                {
                    if (spec.Parameters.Count != 1)
                    {
                        throw new ExprValidationException("The " + EngineImportServiceConstants.EXT_SINGLEROW_FUNCTION_TRANSPOSE + " function requires a single parameter expression");
                    }
                    _exprEvaluator = new ExprDotEvalTransposeAsStream(_chainSpec[0].Parameters[0].ExprEvaluator);
                }
                else if (spec.Parameters.Count != 1)
                {
                    throw HandleNotFound(spec.Name);
                }
                else
                {
                    if (propertyInfoPair == null)
                    {
                        throw new ExprValidationException("Unknown single-row function, aggregation function or mapped or indexed property named '" + spec.Name + "' could not be resolved");
                    }
                    _exprEvaluator       = GetPropertyPairEvaluator(spec.Parameters[0].ExprEvaluator, propertyInfoPair, validationContext);
                    _streamNumReferenced = propertyInfoPair.First.StreamNum;
                }
                return(null);
            }

            // handle the case where the first chain spec element is a stream name.
            ExprValidationException prefixedStreamNumException = null;
            int prefixedStreamNumber = PrefixedStreamName(_chainSpec, validationContext.StreamTypeService);

            if (prefixedStreamNumber != -1)
            {
                ExprChainedSpec specAfterStreamName = _chainSpec[1];

                // Attempt to resolve as property
                Pair <PropertyResolutionDescriptor, string> propertyInfoPair = null;
                try {
                    string propName = _chainSpec[0].Name + "." + specAfterStreamName.Name;
                    propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, propName, streamTypeService.HasPropertyAgnosticType, false);
                }
                catch (ExprValidationPropertyException) {
                    // fine
                }
                if (propertyInfoPair != null)
                {
                    if (specAfterStreamName.Parameters.Count != 1)
                    {
                        throw HandleNotFound(specAfterStreamName.Name);
                    }
                    _exprEvaluator       = GetPropertyPairEvaluator(specAfterStreamName.Parameters[0].ExprEvaluator, propertyInfoPair, validationContext);
                    _streamNumReferenced = propertyInfoPair.First.StreamNum;
                    return(null);
                }

                // Attempt to resolve as event-underlying object instance method
                EventType eventType = validationContext.StreamTypeService.EventTypes[prefixedStreamNumber];
                Type      type      = eventType.UnderlyingType;

                IList <ExprChainedSpec> remainderChain = new List <ExprChainedSpec>(_chainSpec);
                remainderChain.RemoveAt(0);

                ExprValidationException methodEx = null;
                ExprDotEval[]           underlyingMethodChain = null;
                try {
                    EPType typeInfo = EPTypeHelper.SingleValue(type);
                    underlyingMethodChain = ExprDotNodeUtility.GetChainEvaluators(prefixedStreamNumber, typeInfo, remainderChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber)).ChainWithUnpack;
                }
                catch (ExprValidationException ex) {
                    methodEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

                ExprDotEval[]           eventTypeMethodChain = null;
                ExprValidationException enumDatetimeEx       = null;
                try {
                    EPType typeInfo = EPTypeHelper.SingleEvent(eventType);
                    ExprDotNodeRealizedChain chain = ExprDotNodeUtility.GetChainEvaluators(prefixedStreamNumber, typeInfo, remainderChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber));
                    eventTypeMethodChain           = chain.ChainWithUnpack;
                    _exprDotNodeFilterAnalyzerDesc = chain.FilterAnalyzerDesc;
                }
                catch (ExprValidationException ex) {
                    enumDatetimeEx = ex;
                    // expected - may not be able to find the methods on the underlying
                }

                if (underlyingMethodChain != null)
                {
                    _exprEvaluator       = new ExprDotEvalStreamMethod(this, prefixedStreamNumber, underlyingMethodChain);
                    _streamNumReferenced = prefixedStreamNumber;
                }
                else if (eventTypeMethodChain != null)
                {
                    _exprEvaluator       = new ExprDotEvalStreamEventBean(this, prefixedStreamNumber, eventTypeMethodChain);
                    _streamNumReferenced = prefixedStreamNumber;
                }

                if (_exprEvaluator != null)
                {
                    return(null);
                }
                else
                {
                    if (ExprDotNodeUtility.IsDatetimeOrEnumMethod(remainderChain[0].Name))
                    {
                        prefixedStreamNumException = enumDatetimeEx;
                    }
                    else
                    {
                        prefixedStreamNumException = new ExprValidationException("Failed to solve '" + remainderChain[0].Name + "' to either a date-time or enumeration method, an event property or a method on the event underlying object: " + methodEx.Message, methodEx);
                    }
                }
            }

            // There no root node, in this case the classname or property name is provided as part of the chain.
            // Such as "MyClass.myStaticLib(...)" or "mycollectionproperty.doIt(...)"
            //
            IList <ExprChainedSpec> modifiedChain = new List <ExprChainedSpec>(_chainSpec);
            ExprChainedSpec         firstItem     = modifiedChain.Pluck(0);

            Pair <PropertyResolutionDescriptor, string> propertyInfoPairX = null;

            try {
                propertyInfoPairX = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, firstItem.Name, streamTypeService.HasPropertyAgnosticType, true);
            }
            catch (ExprValidationPropertyException) {
                // not a property
            }

            // If property then treat it as such
            if (propertyInfoPairX != null)
            {
                string    propertyName = propertyInfoPairX.First.PropertyName;
                int       streamId     = propertyInfoPairX.First.StreamNum;
                EventType streamType   = streamTypeService.EventTypes[streamId];
                EPType    typeInfo;
                ExprEvaluatorEnumeration enumerationEval = null;
                EPType              inputType;
                ExprEvaluator       rootNodeEvaluator = null;
                EventPropertyGetter getter;

                if (firstItem.Parameters.IsEmpty())
                {
                    getter = streamType.GetGetter(propertyInfoPairX.First.PropertyName);

                    ExprDotEnumerationSourceForProps propertyEval = ExprDotNodeUtility.GetPropertyEnumerationSource(
                        propertyInfoPairX.First.PropertyName, streamId, streamType, hasEnumerationMethod, validationContext.IsDisablePropertyExpressionEventCollCache);
                    typeInfo          = propertyEval.ReturnType;
                    enumerationEval   = propertyEval.Enumeration;
                    inputType         = propertyEval.ReturnType;
                    rootNodeEvaluator = new PropertyExprEvaluatorNonLambda(streamId, getter, propertyInfoPairX.First.PropertyType);
                }
                else
                {
                    // property with parameter - mapped or indexed property
                    EventPropertyDescriptor desc = EventTypeUtility.GetNestablePropertyDescriptor(streamTypeService.EventTypes[propertyInfoPairX.First.StreamNum], firstItem.Name);
                    if (firstItem.Parameters.Count > 1)
                    {
                        throw new ExprValidationException("Property '" + firstItem.Name + "' may not be accessed passing 2 or more parameters");
                    }
                    ExprEvaluator paramEval = firstItem.Parameters[0].ExprEvaluator;
                    typeInfo  = EPTypeHelper.SingleValue(desc.PropertyComponentType);
                    inputType = typeInfo;
                    getter    = null;
                    if (desc.IsMapped)
                    {
                        if (paramEval.ReturnType != typeof(string))
                        {
                            throw new ExprValidationException("Parameter expression to mapped property '" + propertyName + "' is expected to return a string-type value but returns " + paramEval.ReturnType.GetTypeNameFullyQualPretty());
                        }
                        EventPropertyGetterMapped mappedGetter = propertyInfoPairX.First.StreamEventType.GetGetterMapped(propertyInfoPairX.First.PropertyName);
                        if (mappedGetter == null)
                        {
                            throw new ExprValidationException("Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }
                        rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaMapped(streamId, mappedGetter, paramEval, desc.PropertyComponentType);
                    }
                    if (desc.IsIndexed)
                    {
                        if (paramEval.ReturnType.GetBoxedType() != typeof(int?))
                        {
                            throw new ExprValidationException("Parameter expression to mapped property '" + propertyName + "' is expected to return a Integer-type value but returns " + paramEval.ReturnType.GetTypeNameFullyQualPretty());
                        }
                        EventPropertyGetterIndexed indexedGetter = propertyInfoPairX.First.StreamEventType.GetGetterIndexed(propertyInfoPairX.First.PropertyName);
                        if (indexedGetter == null)
                        {
                            throw new ExprValidationException("Mapped property named '" + propertyName + "' failed to obtain getter-object");
                        }
                        rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaIndexed(streamId, indexedGetter, paramEval, desc.PropertyComponentType);
                    }
                }
                if (typeInfo == null)
                {
                    throw new ExprValidationException("Property '" + propertyName + "' is not a mapped or indexed property");
                }

                // try to build chain based on the input (non-fragment)
                ExprDotNodeRealizedChain           evals;
                ExprDotNodeFilterAnalyzerInputProp filterAnalyzerInputProp = new ExprDotNodeFilterAnalyzerInputProp(propertyInfoPairX.First.StreamNum, propertyInfoPairX.First.PropertyName);
                bool rootIsEventBean = false;
                try {
                    evals = ExprDotNodeUtility.GetChainEvaluators(streamId, inputType, modifiedChain, validationContext, _isDuckTyping, filterAnalyzerInputProp);
                }
                catch (ExprValidationException ex) {
                    // try building the chain based on the fragment event type (i.e. A.after(B) based on A-configured start time where A is a fragment)
                    FragmentEventType fragment = propertyInfoPairX.First.FragmentEventType;
                    if (fragment == null)
                    {
                        throw;
                    }

                    EPType fragmentTypeInfo;
                    if (fragment.IsIndexed)
                    {
                        fragmentTypeInfo = EPTypeHelper.CollectionOfEvents(fragment.FragmentType);
                    }
                    else
                    {
                        fragmentTypeInfo = EPTypeHelper.SingleEvent(fragment.FragmentType);
                    }

                    rootIsEventBean   = true;
                    evals             = ExprDotNodeUtility.GetChainEvaluators(propertyInfoPairX.First.StreamNum, fragmentTypeInfo, modifiedChain, validationContext, _isDuckTyping, filterAnalyzerInputProp);
                    rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaFragment(streamId, getter, fragment.FragmentType.UnderlyingType);
                }

                _exprEvaluator = new ExprDotEvalRootChild(hasEnumerationMethod, this, rootNodeEvaluator, enumerationEval, inputType, evals.Chain, evals.ChainWithUnpack, !rootIsEventBean);
                _exprDotNodeFilterAnalyzerDesc = evals.FilterAnalyzerDesc;
                _streamNumReferenced           = propertyInfoPairX.First.StreamNum;
                _rootPropertyName = propertyInfoPairX.First.PropertyName;
                return(null);
            }

            // If variable then resolve as such
            string contextNameVariable = validationContext.VariableService.IsContextVariable(firstItem.Name);

            if (contextNameVariable != null)
            {
                throw new ExprValidationException("Method invocation on context-specific variable is not supported");
            }
            VariableReader variableReader = validationContext.VariableService.GetReader(firstItem.Name, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID);

            if (variableReader != null)
            {
                EPType typeInfo;
                ExprDotStaticMethodWrap wrap;
                if (variableReader.VariableMetaData.VariableType.IsArray)
                {
                    typeInfo = EPTypeHelper.CollectionOfSingleValue(variableReader.VariableMetaData.VariableType.GetElementType());
                    wrap     = new ExprDotStaticMethodWrapArrayScalar(variableReader.VariableMetaData.VariableName, variableReader.VariableMetaData.VariableType.GetElementType());
                }
                else if (variableReader.VariableMetaData.EventType != null)
                {
                    typeInfo = EPTypeHelper.SingleEvent(variableReader.VariableMetaData.EventType);
                    wrap     = null;
                }
                else
                {
                    typeInfo = EPTypeHelper.SingleValue(variableReader.VariableMetaData.VariableType);
                    wrap     = null;
                }

                ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(null, typeInfo, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic());
                _exprEvaluator = new ExprDotEvalVariable(this, variableReader, wrap, evals.ChainWithUnpack);
                return(null);
            }

            // try resolve as enumeration class with value
            object enumconstant = TypeHelper.ResolveIdentAsEnumConst(firstItem.Name, validationContext.MethodResolutionService, null, false);

            if (enumconstant != null)
            {
                // try resolve method
                ExprChainedSpec methodSpec = modifiedChain[0];
                string          enumvalue  = firstItem.Name;
                ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler
                {
                    ProcHandle = ex => new ExprValidationException("Failed to resolve method '" + methodSpec.Name + "' on enumeration value '" + enumvalue + "': " + ex.Message),
                };
                EventType wildcardType            = validationContext.StreamTypeService.EventTypes.Length != 1 ? null : validationContext.StreamTypeService.EventTypes[0];
                ExprNodeUtilMethodDesc methodDesc = ExprNodeUtility.ResolveMethodAllowWildcardAndStream(enumconstant.GetType().Name, enumconstant.GetType(), methodSpec.Name, methodSpec.Parameters, validationContext.MethodResolutionService, validationContext.EventAdapterService, validationContext.StatementId, wildcardType != null, wildcardType, handler, methodSpec.Name, validationContext.TableService);

                // method resolved, hook up
                modifiedChain.RemoveAt(0);        // we identified this piece
                ExprDotStaticMethodWrap optionalLambdaWrap = ExprDotStaticMethodWrapFactory.Make(methodDesc.ReflectionMethod, validationContext.EventAdapterService, modifiedChain);
                EPType typeInfo = optionalLambdaWrap != null ? optionalLambdaWrap.TypeInfo : EPTypeHelper.SingleValue(methodDesc.FastMethod.ReturnType);

                ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(null, typeInfo, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic());
                _exprEvaluator = new ExprDotEvalStaticMethod(validationContext.StatementName, firstItem.Name, methodDesc.FastMethod,
                                                             methodDesc.ChildEvals, false, optionalLambdaWrap, evals.ChainWithUnpack, false, enumconstant);
                return(null);
            }

            // if prefixed by a stream name, we are giving up
            if (prefixedStreamNumException != null)
            {
                throw prefixedStreamNumException;
            }

            // If class then resolve as class
            ExprChainedSpec secondItem = modifiedChain.Pluck(0);

            bool      allowWildcard  = validationContext.StreamTypeService.EventTypes.Length == 1;
            EventType streamZeroType = null;

            if (validationContext.StreamTypeService.EventTypes.Length > 0)
            {
                streamZeroType = validationContext.StreamTypeService.EventTypes[0];
            }

            ExprNodeUtilMethodDesc method = ExprNodeUtility.ResolveMethodAllowWildcardAndStream(firstItem.Name, null, secondItem.Name, secondItem.Parameters, validationContext.MethodResolutionService, validationContext.EventAdapterService, validationContext.StatementId, allowWildcard, streamZeroType, new ExprNodeUtilResolveExceptionHandlerDefault(firstItem.Name + "." + secondItem.Name, false), secondItem.Name, validationContext.TableService);

            bool isConstantParameters = method.IsAllConstants && _isUDFCache;

            _isReturnsConstantResult = isConstantParameters && modifiedChain.IsEmpty();

            // this may return a pair of null if there is no lambda or the result cannot be wrapped for lambda-function use
            ExprDotStaticMethodWrap optionalLambdaWrapX = ExprDotStaticMethodWrapFactory.Make(method.ReflectionMethod, validationContext.EventAdapterService, modifiedChain);
            EPType typeInfoX = optionalLambdaWrapX != null ? optionalLambdaWrapX.TypeInfo : EPTypeHelper.SingleValue(method.ReflectionMethod.ReturnType);

            ExprDotNodeRealizedChain evalsX = ExprDotNodeUtility.GetChainEvaluators(null, typeInfoX, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic());

            _exprEvaluator = new ExprDotEvalStaticMethod(validationContext.StatementName, firstItem.Name, method.FastMethod, method.ChildEvals, isConstantParameters, optionalLambdaWrapX, evalsX.ChainWithUnpack, false, null);
            return(null);
        }
コード例 #7
0
ファイル: EnumAggregateScalar.cs プロジェクト: lanicon/nesper
        public override CodegenExpression Codegen(
            EnumForgeCodegenParams premade,
            CodegenMethodScope codegenMethodScope,
            CodegenClassScope codegenClassScope)
        {
            var typeMember = codegenClassScope.AddDefaultFieldUnshared(
                true,
                typeof(ObjectArrayEventType),
                Cast(typeof(ObjectArrayEventType), EventTypeUtility.ResolveTypeCodegen(_eventType, EPStatementInitServicesConstants.REF)));

            var initializationType = _initialization.EvaluationType;
            var innerType          = _innerExpression.EvaluationType;

            if (innerType != initializationType && innerType == initializationType.GetBoxedType())
            {
                initializationType = innerType;
            }

            var scope      = new ExprForgeCodegenSymbol(false, null);
            var methodNode = codegenMethodScope
                             .MakeChildWithScope(initializationType, typeof(EnumAggregateScalar), scope, codegenClassScope)
                             .AddParam(EnumForgeCodegenNames.PARAMS);

            var block = methodNode.Block;

            block
            .DeclareVar(initializationType, "value", _initialization.EvaluateCodegen(initializationType, methodNode, scope, codegenClassScope))
            .IfCondition(ExprDotMethod(EnumForgeCodegenNames.REF_ENUMCOLL, "IsEmpty"))
            .BlockReturn(Ref("value"));

            block
            .DeclareVar <ObjectArrayEventBean>("@event", NewInstance <ObjectArrayEventBean>(
                                                   NewArrayByLength(typeof(object), Constant(_numParameters)), typeMember))
            .AssignArrayElement(EnumForgeCodegenNames.REF_EPS, Constant(StreamNumLambda), Ref("@event"))
            .DeclareVar <object[]>("props", ExprDotName(Ref("@event"), "Properties"));

            if (_numParameters > 3)
            {
                block.AssignArrayElement("props", Constant(3), ExprDotName(EnumForgeCodegenNames.REF_ENUMCOLL, "Count"));
            }

            if (_numParameters > 2)
            {
                block.DeclareVar <int>("count", Constant(-1));
            }

            var forEach = block.ForEach(typeof(object), "next", EnumForgeCodegenNames.REF_ENUMCOLL)
                          .AssignArrayElement("props", Constant(0), Ref("value"))
                          .AssignArrayElement("props", Constant(1), Ref("next"));

            if (_numParameters > 2)
            {
                forEach
                .IncrementRef("count")
                .AssignArrayElement("props", Constant(2), Ref("count"));
            }

            forEach
            .AssignRef("value", _innerExpression.EvaluateCodegen(innerType, methodNode, scope, codegenClassScope))
            .BlockEnd();

            block.MethodReturn(Ref("value"));

            return(LocalMethod(methodNode, premade.Eps, premade.Enumcoll, premade.IsNewData, premade.ExprCtx));
        }
        public override CodegenExpression EvaluateGetCollEventsCodegen(
            CodegenMethodScope parent,
            ExprSubselectEvalMatchSymbol symbols,
            CodegenClassScope classScope)
        {
            CodegenExpression aggService = classScope.NamespaceScope.AddOrGetDefaultFieldWellKnown(
                new CodegenFieldNameSubqueryAgg(subselect.SubselectNumber),
                typeof(AggregationResultFuture));
            var factory = classScope.AddOrGetDefaultFieldSharable(EventBeanTypedEventFactoryCodegenField.INSTANCE);
            var subselectMultirowType = classScope.AddDefaultFieldUnshared(
                false,
                typeof(EventType),
                EventTypeUtility.ResolveTypeCodegen(
                    subselect.subselectMultirowType,
                    EPStatementInitServicesConstants.REF));

            var method = parent.MakeChild(typeof(FlexCollection), GetType(), classScope);
            var evalCtx = symbols.GetAddExprEvalCtx(method);

            method.Block
                .DeclareVar<int>("cpid", ExprDotName(evalCtx, "AgentInstanceId"))
                .DeclareVar<AggregationService>(
                    "aggregationService",
                    ExprDotMethod(aggService, "GetContextPartitionAggregationService", Ref("cpid")))
                .DeclareVar<ICollection<object>>(
                    "groupKeys",
                    ExprDotMethod(Ref("aggregationService"), "GetGroupKeys", evalCtx))
                .IfCondition(ExprDotMethod(Ref("groupKeys"), "IsEmpty"))
                .BlockReturn(ConstantNull())
                .ApplyTri(DECLARE_EVENTS_SHIFTED, method, symbols)
                .DeclareVar<ICollection<EventBean>>(
                    "result",
                    NewInstance<ArrayDeque<EventBean>>(ExprDotName(Ref("groupKeys"), "Count")));

            var forEach = method.Block.ForEach(typeof(object), "groupKey", Ref("groupKeys"));
            {
                var havingExpr = CodegenLegoMethodExpression.CodegenExpression(subselect.HavingExpr, method, classScope, true);
                CodegenExpression havingCall = LocalMethod(
                    havingExpr,
                    REF_EVENTS_SHIFTED,
                    symbols.GetAddIsNewData(method),
                    evalCtx);

                forEach
                    .ExprDotMethod(
                        Ref("aggregationService"),
                        "SetCurrentAccess",
                        Ref("groupKey"),
                        Ref("cpid"),
                        ConstantNull())
                    .DeclareVar<bool?>("pass", Cast(typeof(bool?), havingCall))
                    .IfCondition(And(NotEqualsNull(Ref("pass")), Unbox(Ref("pass"))))
                    .DeclareVar<IDictionary<string, object>>(
                        "row",
                        LocalMethod(
                            subselect.EvaluateRowCodegen(method, classScope),
                            REF_EVENTS_SHIFTED,
                            ConstantTrue(),
                            symbols.GetAddExprEvalCtx(method)))
                    .DeclareVar<EventBean>(
                        "@event",
                        ExprDotMethod(factory, "AdapterForTypedMap", Ref("row"), subselectMultirowType))
                    .ExprDotMethod(Ref("result"), "Add", Ref("@event"));
            }
            method.Block.MethodReturn(FlexWrap(Ref("result")));
            return LocalMethod(method);
        }
コード例 #9
0
        private static CodegenMethod RegisterEventTypeCodegen(
            EventType eventType,
            CodegenMethodScope parent,
            CodegenClassScope classScope,
            ModuleEventTypeInitializeSymbol symbols)
        {
            var method = parent.MakeChild(typeof(void), typeof(EPCompilerImpl), classScope);

            // metadata
            method.Block.DeclareVar<EventTypeMetadata>("metadata", eventType.Metadata.ToExpression());

            if (eventType is JsonEventType) {
                JsonEventType jsonEventType = (JsonEventType) eventType;
                method.Block.DeclareVar<LinkedHashMap<string, object>>(
                    "props",
                    LocalMethod(
                        MakePropsCodegen(
                            jsonEventType.Types,
                            method,
                            symbols,
                            classScope,
                            () => jsonEventType.DeepSuperTypes.GetEnumerator())));
                string[] superTypeNames = GetSupertypeNames(jsonEventType);
                var detailExpr = jsonEventType.Detail.ToExpression(method, classScope);
                method.Block.Expression(
                    ExprDotMethodChain(symbols.GetAddInitSvc(method))
                        .Get(EPModuleEventTypeInitServicesConstants.GETEVENTTYPECOLLECTOR)
                        .Add(
                            "RegisterJson",
                            Ref("metadata"),
                            Ref("props"),
                            Constant(superTypeNames),
                            Constant(jsonEventType.StartTimestampPropertyName),
                            Constant(jsonEventType.EndTimestampPropertyName),
                            detailExpr));
            }
            else if (eventType is BaseNestableEventType baseNestable) {
                method.Block.DeclareVar<LinkedHashMap<string, object>>(
                    "props",
                    LocalMethod(
                        MakePropsCodegen(
                            baseNestable.Types,
                            method,
                            symbols,
                            classScope,
                            () => baseNestable.DeepSuperTypes.GetEnumerator())));
                var registerMethodName = baseNestable is MapEventType ? "RegisterMap" : "RegisterObjectArray";
                var superTypeNames = GetSupertypeNames(baseNestable);

                method.Block
                    .Expression(
                        ExprDotMethodChain(symbols.GetAddInitSvc(method))
                            .Get(EPModuleEventTypeInitServicesConstants.GETEVENTTYPECOLLECTOR)
                            .Add(
                                registerMethodName,
                                Ref("metadata"),
                                Ref("props"),
                                Constant(superTypeNames),
                                Constant(baseNestable.StartTimestampPropertyName),
                                Constant(baseNestable.EndTimestampPropertyName)));
            }
            else if (eventType is WrapperEventType wrapper) {
                method.Block.DeclareVar<EventType>(
                    "inner",
                    EventTypeUtility.ResolveTypeCodegen(wrapper.UnderlyingEventType, symbols.GetAddInitSvc(method)));
                method.Block.DeclareVar<LinkedHashMap<string, object>>(
                    "props",
                    LocalMethod(
                        MakePropsCodegen(
                            wrapper.UnderlyingMapType.Types,
                            method,
                            symbols,
                            classScope,
                            () => wrapper.UnderlyingMapType.DeepSuperTypes.GetEnumerator())));
                method.Block
                    .Expression(
                        ExprDotMethodChain(symbols.GetAddInitSvc(method))
                            .Get(EPModuleEventTypeInitServicesConstants.GETEVENTTYPECOLLECTOR)
                            .Add("RegisterWrapper", Ref("metadata"), Ref("inner"), Ref("props")));
            }
            else if (eventType is BeanEventType beanType) {
                var superTypes = MakeSupertypes(beanType.SuperTypes, symbols.GetAddInitSvc(method));
                var deepSuperTypes = MakeDeepSupertypes(beanType.DeepSuperTypesCollection, method, symbols, classScope);
                method.Block
                    .Expression(
                        ExprDotMethodChain(symbols.GetAddInitSvc(method))
                            .Get(EPModuleEventTypeInitServicesConstants.GETEVENTTYPECOLLECTOR)
                            .Add(
                                "RegisterBean",
                                Ref("metadata"),
                                Typeof(beanType.UnderlyingType),
                                Constant(beanType.StartTimestampPropertyName),
                                Constant(beanType.EndTimestampPropertyName),
                                superTypes,
                                deepSuperTypes));
            }
            else if (eventType is SchemaXMLEventType xmlType && (xmlType.RepresentsFragmentOfProperty != null)) {
                method.Block
                    .Expression(
                        ExprDotMethodChain(symbols.GetAddInitSvc(method))
                            .Get(EPModuleEventTypeInitServicesConstants.GETEVENTTYPECOLLECTOR)
                            .Add(
                                "RegisterXML",
                                Ref("metadata"),
                                Constant(xmlType.RepresentsFragmentOfProperty),
                                Constant(xmlType.RepresentsOriginalTypeName)));
            }
コード例 #10
0
        // The create window command:
        //      create window windowName[.window_view_list] as [select properties from] type
        //
        // This section expected s single FilterStreamSpecCompiled representing the selected type.
        // It creates a new event type representing the window type and a sets the type selected on the filter stream spec.
        protected internal static CreateWindowCompileResult HandleCreateWindow(
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            var createWindowDesc = @base.StatementSpec.Raw.CreateWindowDesc;
            var columns = createWindowDesc.Columns;
            var typeName = createWindowDesc.WindowName;
            EventType targetType;

            // determine that the window name is not already in use as an event type name
            var existingType = services.EventTypeCompileTimeResolver.GetTypeByName(typeName);
            if (existingType != null && existingType.Metadata.TypeClass != EventTypeTypeClass.NAMED_WINDOW) {
                throw new ExprValidationException(
                    "Error starting statement: An event type or schema by name '" + typeName + "' already exists");
            }

            // Determine select-from
            var optionalSelectFrom = GetOptionalSelectFrom(createWindowDesc, services);

            // Create Map or Wrapper event type from the select clause of the window.
            // If no columns selected, simply create a wrapper type
            // Build a list of properties
            var newSelectClauseSpecRaw = new SelectClauseSpecRaw();
            LinkedHashMap<string, object> properties;
            var hasProperties = false;
            if (columns != null && !columns.IsEmpty()) {
                properties = EventTypeUtility.BuildType(
                    columns,
                    null,
                    services.ImportServiceCompileTime,
                    services.EventTypeCompileTimeResolver);
                hasProperties = true;
            }
            else {
                if (optionalSelectFrom == null) {
                    throw new IllegalStateException("Missing from-type information for create-window");
                }

                // Validate the select expressions which consists of properties only
                var select = CompileLimitedSelect(optionalSelectFrom, @base, services);

                properties = new LinkedHashMap<string, object>();
                foreach (var selectElement in select) {
                    if (selectElement.FragmentType != null) {
                        properties.Put(selectElement.AssignedName, selectElement.FragmentType);
                    }
                    else {
                        properties.Put(selectElement.AssignedName, selectElement.SelectExpressionType);
                    }

                    // Add any properties to the new select clause for use by consumers to the statement itself
                    newSelectClauseSpecRaw.Add(
                        new SelectClauseExprRawSpec(new ExprIdentNodeImpl(selectElement.AssignedName), null, false));
                    hasProperties = true;
                }
            }

            // Create Map or Wrapper event type from the select clause of the window.
            // If no columns selected, simply create a wrapper type
            var isOnlyWildcard = @base.StatementSpec.Raw.SelectClauseSpec.IsOnlyWildcard;
            var isWildcard = @base.StatementSpec.Raw.SelectClauseSpec.IsUsingWildcard;
            var namedWindowVisibility = services.ModuleVisibilityRules.GetAccessModifierNamedWindow(@base, typeName);
            try {
                if (isWildcard && !isOnlyWildcard) {
                    var metadata = new EventTypeMetadata(
                        typeName,
                        @base.ModuleName,
                        EventTypeTypeClass.NAMED_WINDOW,
                        EventTypeApplicationType.WRAPPER,
                        namedWindowVisibility,
                        EventTypeBusModifier.NONBUS,
                        false,
                        EventTypeIdPair.Unassigned());
                    targetType = WrapperEventTypeUtil.MakeWrapper(
                        metadata,
                        optionalSelectFrom.EventType,
                        properties,
                        null,
                        services.BeanEventTypeFactoryPrivate,
                        services.EventTypeCompileTimeResolver);
                }
                else {
                    // Some columns selected, use the types of the columns
                    Func<EventTypeApplicationType, EventTypeMetadata> metadata = type => new EventTypeMetadata(
                        typeName,
                        @base.ModuleName,
                        EventTypeTypeClass.NAMED_WINDOW,
                        type,
                        namedWindowVisibility,
                        EventTypeBusModifier.NONBUS,
                        false,
                        EventTypeIdPair.Unassigned());

                    if (hasProperties && !isOnlyWildcard) {
                        var compiledProperties = EventTypeUtility.CompileMapTypeProperties(
                            properties,
                            services.EventTypeCompileTimeResolver);
                        var representation = EventRepresentationUtil.GetRepresentation(
                            @base.StatementSpec.Annotations,
                            services.Configuration,
                            AssignedType.NONE);

                        if (representation == EventUnderlyingType.MAP) {
                            targetType = BaseNestableEventUtil.MakeMapTypeCompileTime(
                                metadata.Invoke(EventTypeApplicationType.MAP),
                                compiledProperties,
                                null,
                                null,
                                null,
                                null,
                                services.BeanEventTypeFactoryPrivate,
                                services.EventTypeCompileTimeResolver);
                        }
                        else if (representation == EventUnderlyingType.OBJECTARRAY) {
                            targetType = BaseNestableEventUtil.MakeOATypeCompileTime(
                                metadata.Invoke(EventTypeApplicationType.OBJECTARR),
                                compiledProperties,
                                null,
                                null,
                                null,
                                null,
                                services.BeanEventTypeFactoryPrivate,
                                services.EventTypeCompileTimeResolver);
                        }
                        else if (representation == EventUnderlyingType.AVRO) {
                            targetType = services.EventTypeAvroHandler.NewEventTypeFromNormalized(
                                metadata.Invoke(EventTypeApplicationType.AVRO),
                                services.EventTypeCompileTimeResolver,
                                services.BeanEventTypeFactoryPrivate.EventBeanTypedEventFactory,
                                compiledProperties,
                                @base.StatementRawInfo.Annotations,
                                null,
                                null,
                                null,
                                @base.StatementName);
                        }
                        else {
                            throw new IllegalStateException("Unrecognized representation " + representation);
                        }
                    }
                    else {
                        if (optionalSelectFrom == null) {
                            throw new IllegalStateException("Missing from-type information for create-window");
                        }

                        var selectFromType = optionalSelectFrom.EventType;

                        // No columns selected, no wildcard, use the type as is or as a wrapped type
                        if (selectFromType is ObjectArrayEventType) {
                            var oaType = (ObjectArrayEventType) selectFromType;
                            targetType = BaseNestableEventUtil.MakeOATypeCompileTime(
                                metadata.Invoke(EventTypeApplicationType.OBJECTARR),
                                oaType.Types,
                                null,
                                null,
                                oaType.StartTimestampPropertyName,
                                oaType.EndTimestampPropertyName,
                                services.BeanEventTypeFactoryPrivate,
                                services.EventTypeCompileTimeResolver);
                        }
                        else if (selectFromType is AvroSchemaEventType) {
                            var avroSchemaEventType = (AvroSchemaEventType) selectFromType;
                            var avro = new ConfigurationCommonEventTypeAvro();
                            avro.AvroSchema = avroSchemaEventType.Schema;
                            targetType = services.EventTypeAvroHandler.NewEventTypeFromSchema(
                                metadata.Invoke(EventTypeApplicationType.AVRO),
                                services.BeanEventTypeFactoryPrivate.EventBeanTypedEventFactory,
                                avro,
                                null,
                                null);
                        }
                        else if (selectFromType is MapEventType) {
                            var mapType = (MapEventType) selectFromType;
                            targetType = BaseNestableEventUtil.MakeMapTypeCompileTime(
                                metadata.Invoke(EventTypeApplicationType.MAP),
                                mapType.Types,
                                null,
                                null,
                                mapType.StartTimestampPropertyName,
                                mapType.EndTimestampPropertyName,
                                services.BeanEventTypeFactoryPrivate,
                                services.EventTypeCompileTimeResolver);
                        }
                        else if (selectFromType is BeanEventType) {
                            var beanType = (BeanEventType) selectFromType;
                            targetType = new BeanEventType(
                                services.Container,
                                beanType.Stem,
                                metadata.Invoke(EventTypeApplicationType.CLASS),
                                services.BeanEventTypeFactoryPrivate,
                                null,
                                null,
                                beanType.StartTimestampPropertyName,
                                beanType.EndTimestampPropertyName);
                        }
                        else {
                            targetType = WrapperEventTypeUtil.MakeWrapper(
                                metadata.Invoke(EventTypeApplicationType.WRAPPER),
                                selectFromType,
                                new Dictionary<string, object>(),
                                null,
                                services.BeanEventTypeFactoryPrivate,
                                services.EventTypeCompileTimeResolver);
                        }
                    }
                }

                services.EventTypeCompileTimeRegistry.NewType(targetType);
            }
            catch (EPException ex) {
                throw new ExprValidationException(ex.Message, ex);
            }

            var filter = new FilterSpecCompiled(targetType, typeName, new IList<FilterSpecParamForge>[0], null);
            return new CreateWindowCompileResult(
                filter,
                newSelectClauseSpecRaw,
                optionalSelectFrom == null ? null : optionalSelectFrom.EventType);
        }
コード例 #11
0
        public FileSourceLineUnformatted(
            FileSourceFactory factory,
            DataFlowOpInitializeContext context,
            AdapterInputSource inputSource,
            string filenameOrUri,
            string propertyNameLine,
            string propertyNameFile)
        {
            _factory          = factory;
            _inputSource      = inputSource;
            _filenameOrUri    = filenameOrUri;
            _propertyNameLine = propertyNameLine;
            _propertyNameFile = propertyNameFile;

            var outputEventType  = factory.OutputEventType;
            var statementContext = context.AgentInstanceContext.StatementContext;

            if ((outputEventType.PropertyNames.Length != 1 || outputEventType.PropertyDescriptors[0].PropertyType != typeof(string)) &&
                propertyNameLine == null)
            {
                throw new ArgumentException(
                          "Expecting an output event type that has a single property that is of type string, or alternatively specify the 'propertyNameLine' parameter");
            }

            if (outputEventType is ObjectArrayEventType && outputEventType.PropertyDescriptors.Count == 1)
            {
                _lineProcessor = new LineProcessorObjectArray();
            }
            else
            {
                var propertyNameLineToUse = propertyNameLine;
                if (propertyNameLineToUse == null)
                {
                    propertyNameLineToUse = outputEventType.PropertyDescriptors[0].PropertyName;
                }

                if (!outputEventType.IsProperty(propertyNameLineToUse))
                {
                    throw new EPException("Failed to find property name '" + propertyNameLineToUse + "' in type '" + outputEventType.Name + "'");
                }

                Type propertyType;
                try {
                    propertyType = outputEventType.GetPropertyType(propertyNameLineToUse);
                }
                catch (PropertyAccessException ex) {
                    throw new EPException("Invalid property name '" + propertyNameLineToUse + "': " + ex.Message, ex);
                }

                if (propertyType != typeof(string))
                {
                    throw new EPException("Invalid property type for property '" + propertyNameLineToUse + "', expected a property of type String");
                }

                var writeables = EventTypeUtility.GetWriteableProperties(outputEventType, false, false);
                IList <WriteablePropertyDescriptor> writeableList = new List <WriteablePropertyDescriptor>();

                var writeableLine = EventTypeUtility.FindWritable(propertyNameLineToUse, writeables);
                if (writeableLine == null)
                {
                    throw new EPException("Failed to find writable property property '" + propertyNameLineToUse + "', is the property read-only?");
                }

                writeableList.Add(writeableLine);

                if (propertyNameFile != null)
                {
                    var writeableFile = EventTypeUtility.FindWritable(propertyNameFile, writeables);
                    if (writeableFile == null || writeableFile.PropertyType != typeof(string))
                    {
                        throw new EPException("Failed to find writable String-type property '" + propertyNameFile + "', is the property read-only?");
                    }

                    writeableList.Add(writeableFile);
                }

                EventBeanManufacturer manufacturer;
                try {
                    var writables = writeableList.ToArray();
                    manufacturer = EventTypeUtility
                                   .GetManufacturer(outputEventType, writables, statementContext.ImportServiceRuntime, false, statementContext.EventTypeAvroHandler)
                                   .GetManufacturer(statementContext.EventBeanTypedEventFactory);
                }
                catch (EventBeanManufactureException e) {
                    throw new EPException("Event type '" + outputEventType.Name + "' cannot be written to: " + e.Message, e);
                }

                _lineProcessor = new LineProcessorGeneralPurpose(manufacturer);
            }

            if (factory.OutputPortTypes.Length == 2)
            {
                _eofProcessor = GetBeginEndProcessor(context, 1);
            }
            else if (factory.OutputPortTypes.Length == 3)
            {
                _bofProcessor = GetBeginEndProcessor(context, 1);
                _eofProcessor = GetBeginEndProcessor(context, 2);
            }
            else if (factory.OutputPortTypes.Length > 3)
            {
                throw new EPException("Operator only allows up to 3 output ports");
            }
        }
コード例 #12
0
        public static void ValidateStatementKeyAndHash(
            IEnumerable<Supplier<EventType>> typeProvider,
            string contextName,
            StatementSpecCompiled spec,
            StatementCompileTimeServices compileTimeServices)
        {
            StatementSpecCompiledAnalyzerResult streamAnalysis = StatementSpecCompiledAnalyzer.AnalyzeFilters(spec);
            IList<FilterSpecCompiled> filters = streamAnalysis.Filters;

            var isCreateWindow = spec.Raw.CreateWindowDesc != null;

            // if no create-window: at least one of the filters must match one of the filters specified by the context
            if (!isCreateWindow) {
                foreach (var filter in filters) {
                    foreach (var item in typeProvider) {
                        EventType itemEventType = item.Invoke();
                        var stmtFilterType = filter.FilterForEventType;
                        if (ReferenceEquals(stmtFilterType, itemEventType)) {
                            return;
                        }

                        if (EventTypeUtility.IsTypeOrSubTypeOf(stmtFilterType, itemEventType)) {
                            return;
                        }

                        NamedWindowMetaData namedWindow =
                            compileTimeServices.NamedWindowCompileTimeResolver.Resolve(stmtFilterType.Name);
                        if (namedWindow != null) {
                            string namedWindowContextName = namedWindow.ContextName;
                            if (namedWindowContextName != null && namedWindowContextName.Equals(contextName)) {
                                return;
                            }
                        }
                    }
                }

                if (!filters.IsEmpty()) {
                    throw new ExprValidationException(
                        GetTypeValidationMessage(contextName, filters[0].FilterForEventType.Name));
                }

                return;
            }

            // validate create-window with column definition: not allowed, requires typed
            if (spec.Raw.CreateWindowDesc.Columns != null &&
                spec.Raw.CreateWindowDesc.Columns.Count > 0) {
                throw new ExprValidationException(
                    "Segmented context '" +
                    contextName +
                    "' requires that named windows are associated to an existing event type and that the event type is listed among the partitions defined by the create-context statement");
            }

            // validate create-window declared type
            var declaredAsName = spec.Raw.CreateWindowDesc.AsEventTypeName;
            if (declaredAsName != null) {
                foreach (var item in typeProvider) {
                    EventType itemEventType = item.Invoke();
                    if (itemEventType.Name.Equals(declaredAsName)) {
                        return;
                    }
                }

                throw new ExprValidationException(GetTypeValidationMessage(contextName, declaredAsName));
            }
        }
コード例 #13
0
        private DataFlowOpForgeInitializeResult InitializeTypeDeclared(
            DataFlowOpOutputPort port,
            DataFlowOpForgeInitializeContext context)
        {
            produceEventBean = port.OptionalDeclaredType != null && !port.OptionalDeclaredType.IsUnderlying;

            // compile properties to populate
            outputEventType = port.OptionalDeclaredType.EventType;
            var props = allProperties.Keys;
            props.RemoveAll(PARAMETER_PROPERTIES);
            var writables = SetupProperties(props.ToArray(), outputEventType);
            try {
                eventBeanManufacturer = EventTypeUtility.GetManufacturer(
                    outputEventType,
                    writables,
                    context.Services.ImportServiceCompileTime,
                    false,
                    context.Services.EventTypeAvroHandler);
            }
            catch (EventBeanManufactureException e) {
                throw new ExprValidationException(
                    "Cannot manufacture event for the provided type '" + outputEventType.Name + "': " + e.Message,
                    e);
            }

            var index = 0;
            evaluatorForges = new ExprForge[writables.Length];
            var typeWidenerCustomizer =
                context.Services.EventTypeAvroHandler.GetTypeWidenerCustomizer(outputEventType);
            foreach (var writable in writables) {
                object providedProperty = allProperties.Get(writable.PropertyName);
                var exprNode = (ExprNode) providedProperty;
                var validated = EPLValidationUtil.ValidateSimpleGetSubtree(
                    ExprNodeOrigin.DATAFLOWBEACON,
                    exprNode,
                    null,
                    false,
                    context.Base.StatementRawInfo,
                    context.Services);
                TypeWidenerSPI widener;
                try {
                    widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(validated),
                        validated.Forge.EvaluationType,
                        writable.PropertyType,
                        writable.PropertyName,
                        false,
                        typeWidenerCustomizer,
                        context.Base.StatementName);
                }
                catch (TypeWidenerException e) {
                    throw new ExprValidationException("Failed for property '" + writable.PropertyName + "'", e);
                }

                if (widener != null) {
                    evaluatorForges[index] = new ExprEvalWithTypeWidener(widener, validated, writable.PropertyType);
                }
                else {
                    evaluatorForges[index] = validated.Forge;
                }

                index++;
            }

            return null;
        }
コード例 #14
0
        public static CodegenExpression Codegen(
            EnumOrderByAscDescScalarLambdaForge forge,
            EnumForgeCodegenParams args,
            CodegenMethodScope codegenMethodScope,
            CodegenClassScope codegenClassScope)
        {
            var resultTypeMember = codegenClassScope.AddDefaultFieldUnshared(
                true,
                typeof(ObjectArrayEventType),
                Cast(
                    typeof(ObjectArrayEventType),
                    EventTypeUtility.ResolveTypeCodegen(forge.resultEventType, EPStatementInitServicesConstants.REF)));
            var innerBoxedType = Boxing.GetBoxedType(forge.InnerExpression.EvaluationType);

            var paramTypes = EnumForgeCodegenNames.PARAMS;
            var scope = new ExprForgeCodegenSymbol(false, null);
            var methodNode = codegenMethodScope.MakeChildWithScope(
                    typeof(FlexCollection),
                    typeof(EnumOrderByAscDescScalarLambdaForgeEval),
                    scope,
                    codegenClassScope)
                .AddParam(paramTypes);

            var block = methodNode.Block
                .DeclareVar<OrderedDictionary<object, object>>(
                    "sort",
                    NewInstance(typeof(OrderedDictionary<object, object>)))
                .DeclareVar<bool>("hasColl", ConstantFalse())
                .DeclareVar<ObjectArrayEventBean>(
                    "resultEvent",
                    NewInstance<ObjectArrayEventBean>(NewArrayByLength(typeof(object), Constant(1)), resultTypeMember))
                .AssignArrayElement(EnumForgeCodegenNames.REF_EPS, Constant(forge.StreamNumLambda), Ref("resultEvent"))
                .DeclareVar<object[]>("props", ExprDotName(Ref("resultEvent"), "Properties"));

            block.ForEach(typeof(object), "next", EnumForgeCodegenNames.REF_ENUMCOLL)
                .AssignArrayElement("props", Constant(0), Ref("next"))
                .DeclareVar(
                    innerBoxedType,
                    "value",
                    forge.InnerExpression.EvaluateCodegen(innerBoxedType, methodNode, scope, codegenClassScope))
                .DeclareVar<object>("entry", ExprDotMethod(Ref("sort"), "Get", Ref("value")))
                .IfCondition(EqualsNull(Ref("entry")))
                .Expression(ExprDotMethod(Ref("sort"), "Put", Ref("value"), Ref("next")))
                .BlockContinue()
                .IfCondition(InstanceOf(Ref("entry"), typeof(ICollection<object>)))
                .ExprDotMethod(Cast(typeof(ICollection<object>), Ref("entry")), "Add", Ref("next"))
                .BlockContinue()
                .DeclareVar<Deque<object>>("coll", NewInstance<ArrayDeque<object>>(Constant(2)))
                .ExprDotMethod(Ref("coll"), "Add", Ref("entry"))
                .ExprDotMethod(Ref("coll"), "Add", Ref("next"))
                .ExprDotMethod(Ref("sort"), "Put", Ref("value"), Ref("coll"))
                .AssignRef("hasColl", ConstantTrue())
                .BlockEnd();
            block.MethodReturn(
                FlexWrap(
                    StaticMethod(
                        typeof(EnumOrderByAscDescEventsForgeEval),
                        "EnumOrderBySortEval",
                        Ref("sort"),
                        Ref("hasColl"),
                        Constant(forge.descending))));
            return LocalMethod(methodNode, args.Eps, args.Enumcoll, args.IsNewData, args.ExprCtx);
        }
コード例 #15
0
 internal static bool DetermineSubquerySameStream(StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec)
 {
     foreach (ExprSubselectNode subselect in statementSpec.SubSelectExpressions)
     {
         StreamSpecCompiled streamSpec = subselect.StatementSpecCompiled.StreamSpecs[0];
         if (!(streamSpec is FilterStreamSpecCompiled))
         {
             continue;
         }
         FilterStreamSpecCompiled filterStream = (FilterStreamSpecCompiled)streamSpec;
         EventType typeSubselect = filterStream.FilterSpec.FilterForEventType;
         EventType typeFiltered  = filterStreamSpec.FilterSpec.FilterForEventType;
         if (EventTypeUtility.IsTypeOrSubTypeOf(typeSubselect, typeFiltered) || EventTypeUtility.IsTypeOrSubTypeOf(typeFiltered, typeSubselect))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #16
0
 public CodegenExpression Make(CodegenExpressionRef addInitSvc)
 {
     return NewInstance<ContextControllerKeyedValidationItem>(
         EventTypeUtility.ResolveTypeCodegen(EventType, addInitSvc),
         Constant(PropertyNames));
 }
コード例 #17
0
ファイル: ExprNodeScript.cs プロジェクト: qinfengzhu/nesper
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (_evaluator != null)
            {
                return(null);
            }

            if (Script.ParameterNames.Count != Parameters.Count)
            {
                throw new ExprValidationException(
                          string.Format(
                              "Invalid number of parameters for script '{0}', expected {1} parameters but received {2} parameters",
                              Script.Name,
                              Script.ParameterNames.Count,
                              Parameters.Count));
            }

            // validate all expression parameters
            var validatedParameters = Parameters
                                      .Select(
                expr => ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.SCRIPTPARAMS, expr, validationContext))
                                      .ToList();

            // set up map of input parameter names and evaluators
            var inputParamNames = new string[Script.ParameterNames.Count];
            var evaluators      = new ExprEvaluator[Script.ParameterNames.Count];

            for (int i = 0; i < Script.ParameterNames.Count; i++)
            {
                inputParamNames[i] = Script.ParameterNames[i];
                evaluators[i]      = validatedParameters[i].ExprEvaluator;
            }

            // Compile script
            if (Script.Compiled == null)
            {
                CompileScript(validationContext.ScriptingService, evaluators, validationContext.EngineImportService);
            }

            // Determine declared return type
            Type declaredReturnType = GetDeclaredReturnType(Script.OptionalReturnTypeName, validationContext);

            if (Script.IsOptionalReturnTypeIsArray && declaredReturnType != null)
            {
                declaredReturnType = TypeHelper.GetArrayType(declaredReturnType);
            }
            Type returnType;

            if (Script.Compiled.KnownReturnType == null && Script.OptionalReturnTypeName == null)
            {
                returnType = typeof(Object);
            }
            else if (Script.Compiled.KnownReturnType != null)
            {
                if (declaredReturnType == null)
                {
                    returnType = Script.Compiled.KnownReturnType;
                }
                else
                {
                    Type knownReturnType = Script.Compiled.KnownReturnType;
                    if (declaredReturnType.IsArray && knownReturnType.IsArray)
                    {
                        // we are fine
                    }
                    else if (!knownReturnType.IsAssignmentCompatible(declaredReturnType))
                    {
                        throw new ExprValidationException(
                                  "Return type and declared type not compatible for script '" + Script.Name +
                                  "', known return type is " + knownReturnType.Name + " versus declared return type " +
                                  declaredReturnType.Name);
                    }
                    returnType = declaredReturnType;
                }
            }
            else
            {
                returnType = declaredReturnType;
            }
            if (returnType == null)
            {
                returnType = typeof(Object);
            }

            EventType eventTypeCollection = null;

            if (Script.OptionalEventTypeName != null)
            {
                if (returnType.IsArray && returnType.GetElementType() == typeof(EventBean))
                {
                    eventTypeCollection = EventTypeUtility.RequireEventType(
                        "Script", Script.Name, validationContext.EventAdapterService, Script.OptionalEventTypeName);
                }
                else
                {
                    throw new ExprValidationException(EventTypeUtility.DisallowedAtTypeMessage());
                }
            }

            // Prepare evaluator - this sets the evaluator
            PrepareEvaluator(
                validationContext.StatementName, inputParamNames, evaluators, returnType, eventTypeCollection);
            return(null);
        }
コード例 #18
0
ファイル: FileSourceCSV.cs プロジェクト: hahanonym/nesper
        private static ParseMakePropertiesDesc SetupProperties(bool requireOneMatch,
                                                               string[] propertyNamesOffered,
                                                               EventType outputEventType,
                                                               StatementContext statementContext,
                                                               string dateFormat)
        {
            var writeables = EventTypeUtility.GetWriteableProperties(outputEventType, false);

            IList <int> indexesList = new List <int>();
            IList <SimpleTypeParser>            parserList    = new List <SimpleTypeParser>();
            IList <WriteablePropertyDescriptor> writablesList = new List <WriteablePropertyDescriptor>();

            for (var i = 0; i < propertyNamesOffered.Length; i++)
            {
                var  propertyName = propertyNamesOffered[i];
                Type propertyType;
                try {
                    propertyType = outputEventType.GetPropertyType(propertyName);
                }
                catch (PropertyAccessException ex) {
                    throw new EPException("Invalid property name '" + propertyName + "': " + ex.Message, ex);
                }

                if (propertyType == null)
                {
                    continue;
                }

                SimpleTypeParser parser;
                if ((propertyType == typeof(DateTime)) ||
                    (propertyType == typeof(DateTimeOffset)) ||
                    (propertyType == typeof(DateTimeEx)))
                {
                    var dateTimeFormat = dateFormat != null
                                                ? DateTimeFormat.For(dateFormat)
                                                : DateTimeFormat.ISO_DATE_TIME;

                    if (propertyType == typeof(DateTime?))
                    {
                        parser = new ProxySimpleTypeParser(
                            text => (dateTimeFormat.Parse(text)?.DateTime)?.DateTime);
                    }
                    else if (propertyType == typeof(DateTime))
                    {
                        parser = new ProxySimpleTypeParser(
                            text => dateTimeFormat.Parse(text).DateTime.DateTime);
                    }
                    else if (propertyType == typeof(DateTimeOffset?))
                    {
                        parser = new ProxySimpleTypeParser(
                            text => dateTimeFormat.Parse(text)?.DateTime);
                    }
                    else if (propertyType == typeof(DateTimeOffset))
                    {
                        parser = new ProxySimpleTypeParser(
                            text => dateTimeFormat.Parse(text).DateTime);
                    }
                    else
                    {
                        parser = new ProxySimpleTypeParser(
                            text => dateTimeFormat.Parse(text));
                    }
                }
                else
                {
                    parser = SimpleTypeParserFactory.GetParser(propertyType);
                }

                var writable = EventTypeUtility.FindWritable(propertyName, writeables);
                if (writable == null)
                {
                    continue;
                }

                indexesList.Add(i);
                parserList.Add(parser);
                writablesList.Add(writable);
            }

            if (indexesList.IsEmpty() && requireOneMatch)
            {
                throw new EPException(
                          "Failed to match any of the properties " +
                          CompatExtensions.RenderAny(propertyNamesOffered) +
                          " to the event type properties of event type '" +
                          outputEventType.Name +
                          "'");
            }

            var parsers   = parserList.ToArray();
            var writables = writablesList.ToArray();
            var indexes   = CollectionUtil.IntArray(indexesList);
            EventBeanManufacturer manufacturer;

            try {
                manufacturer = EventTypeUtility.GetManufacturer(
                    outputEventType,
                    writables,
                    statementContext.ImportServiceRuntime,
                    false,
                    statementContext.EventTypeAvroHandler)
                               .GetManufacturer(statementContext.EventBeanTypedEventFactory);
            }
            catch (EventBeanManufactureException e) {
                throw new EPException("Event type '" + outputEventType.Name + "' cannot be written to: " + e.Message, e);
            }

            return(new ParseMakePropertiesDesc(indexes, parsers, manufacturer));
        }
コード例 #19
0
        /// <summary>
        /// Set the preconfigured event properties resolved by XPath expression.
        /// </summary>
        /// <param name="explicitXPathProperties">are preconfigured event properties</param>
        /// <param name="additionalSchemaProperties">the explicit properties</param>
        protected void Initialize(ICollection <ConfigurationEventTypeXMLDOM.XPathPropertyDesc> explicitXPathProperties,
                                  IList <ExplicitPropertyDescriptor> additionalSchemaProperties)
        {
            // make sure we override those explicitly provided with those derived from a metadataz
            var namedProperties = new LinkedHashMap <String, ExplicitPropertyDescriptor>();

            foreach (ExplicitPropertyDescriptor desc in additionalSchemaProperties)
            {
                namedProperties[desc.Descriptor.PropertyName] = desc;
            }

            String xPathExpression = null;

            try
            {
                foreach (ConfigurationEventTypeXMLDOM.XPathPropertyDesc property in explicitXPathProperties)
                {
                    xPathExpression = property.XPath;
                    if (Log.IsInfoEnabled)
                    {
                        Log.Info("Compiling XPath expression for property '" + property.Name + "' as '" +
                                 xPathExpression + "'");
                    }

                    var expressionContext = NamespaceContext ?? GetExtendedContext();
                    var expression        = XPathExpression.Compile(xPathExpression, expressionContext);

                    FragmentFactoryXPathPredefinedGetter fragmentFactory = null;

                    var isFragment = false;
                    if (property.OptionalEventTypeName != null)
                    {
                        fragmentFactory = new FragmentFactoryXPathPredefinedGetter(
                            EventAdapterService,
                            property.OptionalEventTypeName,
                            property.Name);
                        isFragment = true;
                    }

                    var getter = new XPathPropertyGetter(
                        property.Name,
                        xPathExpression,
                        expression,
                        property.ResultType,
                        property.OptionalCastToType,
                        fragmentFactory);
                    var returnType = SchemaUtil.ToReturnType(
                        property.ResultType,
                        property.OptionalCastToType);
                    var indexType = returnType.GetIndexType();
                    var isIndexed = indexType != null;

                    if (property.ResultType == XPathResultType.NodeSet)
                    {
                        isIndexed = true;
                    }

                    var desc = new EventPropertyDescriptor(
                        property.Name, returnType, indexType, false, false,
                        isIndexed, false, isFragment);
                    var @explicit = new ExplicitPropertyDescriptor(
                        desc, getter, isIndexed,
                        property.OptionalEventTypeName);

                    namedProperties[desc.PropertyName] = @explicit;
                }
            }
            catch (XPathException ex)
            {
                throw new EPException(
                          "XPath expression could not be compiled for expression '" + xPathExpression + '\'', ex);
            }

            Initialize(namedProperties.Values);

            // evaluate start and end timestamp properties if any
            _startTimestampPropertyName = ConfigurationEventTypeXMLDOM.StartTimestampPropertyName;
            _endTimestampPropertyName   = ConfigurationEventTypeXMLDOM.EndTimestampPropertyName;
            EventTypeUtility.ValidateTimestampProperties(this, _startTimestampPropertyName, _endTimestampPropertyName);
        }
コード例 #20
0
 public CodegenExpression Make(CodegenExpressionRef addInitSvc)
 {
     return NewInstance<ContextControllerCategoryValidation>(
         EventTypeUtility.ResolveTypeCodegen(CategoryEventType, addInitSvc));
 }
コード例 #21
0
ファイル: AvroSchemaUtil.cs プロジェクト: lanicon/nesper
        public static void AssembleField(
            string propertyName,
            object propertyType,
            JArray assembler,
            Attribute[] annotations,
            ConfigurationCommonEventTypeMeta.AvroSettingsConfig avroSettings,
            EventTypeNameResolver eventTypeNameResolver,
            string statementName,
            TypeRepresentationMapper optionalMapper)
        {
            if (propertyName.Contains(".")) {
                throw new EPException(
                    "Invalid property name as Avro does not allow dot '.' in field names (property '" +
                    propertyName +
                    "')");
            }

            Schema schema = GetAnnotationSchema(propertyName, annotations);
            if (schema != null) {
                assembler.Add(TypeBuilder.Field(propertyName, schema));
                // assembler.Name(propertyName).Type(schema).NoDefault();
                return;
            }

            if (optionalMapper != null && propertyType is Type propertyTypeType) {
                var schemaResult = optionalMapper.Map(
                    new TypeRepresentationMapperContext(propertyTypeType, propertyName, statementName));
                if (schemaResult is JToken schemaAsJsonToken) {
                    assembler.Add(TypeBuilder.Field(propertyName, schemaAsJsonToken));
                    return;
                }
                if (schemaResult is Schema schemaFromResult) {
                    assembler.Add(TypeBuilder.Field(propertyName, schemaFromResult));
                    // assembler.Name(propertyName).Type(result).NoDefault();
                    return;
                }
            }

            if (propertyType == null) {
                assembler.Add(TypeBuilder.Field(propertyName, TypeBuilder.NullType()));
                // assembler.Name(propertyName).Type("null");
            }
            else if (propertyType is string) {
                string propertyTypeName = propertyType.ToString();
                bool isArray = EventTypeUtility.IsPropertyArray(propertyTypeName);
                if (isArray) {
                    propertyTypeName = EventTypeUtility.GetPropertyRemoveArray(propertyTypeName);
                }

                // Add EventType itself as a property
                EventType eventType = eventTypeNameResolver.GetTypeByName(propertyTypeName);
                if (!(eventType is AvroEventType)) {
                    throw new EPException(
                        "Type definition encountered an unexpected property type name '" +
                        propertyType +
                        "' for property '" +
                        propertyName +
                        "', expected the name of a previously-declared Avro type");
                }

                schema = ((AvroEventType) eventType).SchemaAvro;

                if (!isArray) {
                    assembler.Add(TypeBuilder.Field(propertyName, schema));
                }
                else {
                    assembler.Add(TypeBuilder.Field(propertyName, TypeBuilder.Array(schema)));
                }
            }
            else if (propertyType is EventType) {
                var eventType = (EventType) propertyType;
                CheckCompatibleType(eventType);
                if (eventType is AvroEventType) {
                    schema = ((AvroEventType) eventType).SchemaAvro;
                    assembler.Add(TypeBuilder.Field(propertyName, schema));
                }
                else if (eventType is MapEventType) {
                    var mapEventType = (MapEventType) eventType;
                    var nestedSchema = AssembleNestedSchema(
                        mapEventType,
                        avroSettings,
                        annotations,
                        eventTypeNameResolver,
                        statementName,
                        optionalMapper);
                    assembler.Add(TypeBuilder.Field(propertyName, nestedSchema));
                }
                else {
                    throw new IllegalStateException("Unrecognized event type " + eventType);
                }
            }
            else if (propertyType is EventType[]) {
                EventType eventType = ((EventType[]) propertyType)[0];
                CheckCompatibleType(eventType);
                if (eventType is AvroEventType) {
                    schema = ((AvroEventType) eventType).SchemaAvro;
                    assembler.Add(TypeBuilder.Field(propertyName, TypeBuilder.Array(schema)));
                }
                else if (eventType is MapEventType) {
                    var mapEventType = (MapEventType) eventType;
                    var nestedSchema = AssembleNestedSchema(
                        mapEventType,
                        avroSettings,
                        annotations,
                        eventTypeNameResolver,
                        statementName,
                        optionalMapper);

                    assembler.Add(TypeBuilder.Field(propertyName, TypeBuilder.Array(nestedSchema)));
                }
                else {
                    throw new IllegalStateException("Unrecognized event type " + eventType);
                }
            }
            else if (propertyType is Type) {
                var propertyClass = (Type) propertyType;
                var propertyClassBoxed = propertyClass.GetBoxedType();
                bool nullable = propertyClass == propertyClassBoxed;
                bool preferNonNull = avroSettings.IsEnableSchemaDefaultNonNull;
                if (propertyClassBoxed == typeof(bool?)) {
                    AssemblePrimitive(nullable, REQ_BOOLEAN, OPT_BOOLEAN, assembler, propertyName, preferNonNull);
                }
                else if (propertyClassBoxed == typeof(int?) || propertyClassBoxed == typeof(byte?)) {
                    AssemblePrimitive(nullable, REQ_INT, OPT_INT, assembler, propertyName, preferNonNull);
                }
                else if (propertyClassBoxed == typeof(long?)) {
                    AssemblePrimitive(nullable, REQ_LONG, OPT_LONG, assembler, propertyName, preferNonNull);
                }
                else if (propertyClassBoxed == typeof(float?)) {
                    AssemblePrimitive(nullable, REQ_FLOAT, OPT_FLOAT, assembler, propertyName, preferNonNull);
                }
                else if (propertyClassBoxed == typeof(double?)) {
                    AssemblePrimitive(nullable, REQ_DOUBLE, OPT_DOUBLE, assembler, propertyName, preferNonNull);
                }
                else if (propertyClass == typeof(string)) {
                    if (avroSettings.IsEnableNativeString) {
                        if (preferNonNull) {
                            assembler.Add(
                                TypeBuilder.Field(
                                    propertyName,
                                    TypeBuilder.Primitive(
                                        "string",
                                        TypeBuilder.Property(
                                            AvroConstant.PROP_STRING_KEY,
                                            AvroConstant.PROP_STRING_VALUE))));
                        }
                        else {
                            assembler.Add(
                                TypeBuilder.Field(
                                    propertyName,
                                    TypeBuilder.Union(
                                        TypeBuilder.NullType(),
                                        TypeBuilder.StringType(
                                            TypeBuilder.Property(
                                                AvroConstant.PROP_STRING_KEY,
                                                AvroConstant.PROP_STRING_VALUE)))));
                        }
                    }
                    else {
                        AssemblePrimitive(nullable, REQ_STRING, OPT_STRING, assembler, propertyName, preferNonNull);
                    }
                }
                else if (propertyClass == typeof(byte[])) {
                    if (preferNonNull) {
                        assembler.Add(TypeBuilder.RequiredBytes(propertyName));
                    }
                    else {
                        assembler.Add(
                            TypeBuilder.Field(
                                propertyName,
                                TypeBuilder.Union(
                                    TypeBuilder.NullType(),
                                    TypeBuilder.BytesType())));
                    }
                }
                else if (propertyClass.IsArray) {
                    var componentType = propertyClass.GetElementType();
                    var componentTypeBoxed = componentType.GetBoxedType();
                    var nullableElements = componentType == componentTypeBoxed;

                    if (componentTypeBoxed == typeof(bool?)) {
                        AssembleArray(
                            nullableElements,
                            ARRAY_OF_REQ_BOOLEAN,
                            ARRAY_OF_OPT_BOOLEAN,
                            assembler,
                            propertyName,
                            preferNonNull);
                    }
                    else if (componentTypeBoxed == typeof(int?)) {
                        AssembleArray(
                            nullableElements,
                            ARRAY_OF_REQ_INT,
                            ARRAY_OF_OPT_INT,
                            assembler,
                            propertyName,
                            preferNonNull);
                    }
                    else if (componentTypeBoxed == typeof(long?)) {
                        AssembleArray(
                            nullableElements,
                            ARRAY_OF_REQ_LONG,
                            ARRAY_OF_OPT_LONG,
                            assembler,
                            propertyName,
                            preferNonNull);
                    }
                    else if (componentTypeBoxed == typeof(float?)) {
                        AssembleArray(
                            nullableElements,
                            ARRAY_OF_REQ_FLOAT,
                            ARRAY_OF_OPT_FLOAT,
                            assembler,
                            propertyName,
                            preferNonNull);
                    }
                    else if (componentTypeBoxed == typeof(double?)) {
                        AssembleArray(
                            nullableElements,
                            ARRAY_OF_REQ_DOUBLE,
                            ARRAY_OF_OPT_DOUBLE,
                            assembler,
                            propertyName,
                            preferNonNull);
                    }
                    else if (componentTypeBoxed == typeof(byte?)) {
                        AssembleArray(
                            nullableElements,
                            ARRAY_OF_REQ_INT,
                            ARRAY_OF_OPT_INT,
                            assembler,
                            propertyName,
                            preferNonNull);
                    }
                    else if (propertyClass == typeof(string[])) {
                        JObject array;
                        if (avroSettings.IsEnableNativeString) {
                            array = TypeBuilder.Array(
                                TypeBuilder.StringType(
                                    TypeBuilder.Property(
                                        AvroConstant.PROP_STRING_KEY,
                                        AvroConstant.PROP_STRING_VALUE)));
                        }
                        else {
                            array = TypeBuilder.Array(TypeBuilder.StringType());
                        }

                        if (preferNonNull) {
                            assembler.Add(TypeBuilder.Field(propertyName, array));
                        }
                        else {
                            assembler.Add(
                                TypeBuilder.Field(
                                    propertyName,
                                    TypeBuilder.Union(
                                        TypeBuilder.NullType(),
                                        array)));
                        }
                    }
                    else if (propertyClass.CanUnwrap<object>()) {
                    }
                    else {
                        throw MakeEPException(propertyName, propertyType);
                    }
                }
                else if (propertyClass.IsGenericDictionary()) {
                    JToken value;
                    if (avroSettings.IsEnableNativeString) {
                        value = TypeBuilder.StringType(
                            TypeBuilder.Property(AvroConstant.PROP_STRING_KEY, AvroConstant.PROP_STRING_VALUE));
                    }
                    else {
                        value = TypeBuilder.StringType();
                    }

                    if (preferNonNull) {
                        assembler.Add(TypeBuilder.Field(propertyName, TypeBuilder.Map(value)));
                    }
                    else {
                        assembler.Add(
                            TypeBuilder.Field(
                                propertyName,
                                TypeBuilder.Union(
                                    TypeBuilder.NullType(),
                                    TypeBuilder.Map(value))));
                    }
                }
                else if (propertyClass.IsGenericCollection()) {
                    AssembleFieldForCollection(
                        propertyName,
                        propertyType,
                        assembler,
                        avroSettings,
                        propertyClass,
                        preferNonNull);
                }
                else {
                    throw MakeEPException(propertyName, propertyType);
                }
            }
            else {
                throw MakeEPException(propertyName, propertyType);
            }
        }
コード例 #22
0
        public static ExprDotEnumerationSourceForgeForProps GetPropertyEnumerationSource(
            string propertyName,
            int streamId,
            EventType streamType,
            bool allowEnumType,
            bool disablePropertyExpressionEventCollCache)
        {
            var propertyType = streamType.GetPropertyType(propertyName);
            var typeInfo = EPTypeHelper.SingleValue(propertyType); // assume scalar for now

            // no enumeration methods, no need to expose as an enumeration
            if (!allowEnumType) {
                return new ExprDotEnumerationSourceForgeForProps(null, typeInfo, streamId, null);
            }

            var fragmentEventType = streamType.GetFragmentType(propertyName);
            var getter = ((EventTypeSPI) streamType).GetGetterSPI(propertyName);

            ExprEnumerationForge enumEvaluator = null;
            if (getter != null && fragmentEventType != null) {
                if (fragmentEventType.IsIndexed) {
                    enumEvaluator = new PropertyDotEventCollectionForge(
                        propertyName,
                        streamId,
                        fragmentEventType.FragmentType,
                        getter,
                        disablePropertyExpressionEventCollCache);
                    typeInfo = EPTypeHelper.CollectionOfEvents(fragmentEventType.FragmentType);
                }
                else { // we don't want native to require an eventbean instance
                    enumEvaluator = new PropertyDotEventSingleForge(streamId, fragmentEventType.FragmentType, getter);
                    typeInfo = EPTypeHelper.SingleEvent(fragmentEventType.FragmentType);
                }
            }
            else {
                var desc = EventTypeUtility.GetNestablePropertyDescriptor(streamType, propertyName);
                if (desc != null && desc.IsIndexed && !desc.IsRequiresIndex && desc.PropertyComponentType != null) {
                    if (propertyType == typeof(string)) {
                        enumEvaluator = new PropertyDotScalarStringForge(
                            propertyName,
                            streamId,
                            getter);
                    }
                    else if (propertyType.IsArray) {
                        enumEvaluator = new PropertyDotScalarArrayForge(
                            propertyName,
                            streamId,
                            getter,
                            desc.PropertyComponentType,
                            desc.PropertyType);
                    }
                    else if (propertyType.IsGenericCollection()) {
                        enumEvaluator = new PropertyDotScalarCollection(
                            propertyName,
                            streamId,
                            getter,
                            desc.PropertyComponentType);
                    }
                    else if (propertyType.IsGenericEnumerable()) {
                        enumEvaluator = new PropertyDotScalarIterable(
                            propertyName,
                            streamId,
                            getter,
                            desc.PropertyComponentType,
                            propertyType);
                    }
                    else {
                        throw new IllegalStateException(
                            "Property indicated indexed-type but failed to find proper collection adapter for use with enumeration methods");
                    }

                    typeInfo = EPTypeHelper.CollectionOfSingleValue(
                        desc.PropertyComponentType,
                        desc.PropertyType);
                }
            }

            return new ExprDotEnumerationSourceForgeForProps(
                enumEvaluator,
                typeInfo,
                streamId,
                (ExprEnumerationGivenEventForge) enumEvaluator);
        }
コード例 #23
0
        public static FilterValueSetParam[][] GetAddendumFilters(
            object getterKey,
            FilterSpecActivatable filtersSpec, 
            ContextControllerDetailKeyed keyedSpec,
            bool includePartition,
            ContextControllerStatementDesc optionalStatementDesc,
            IDictionary<int, ContextControllerStatementDesc> statements,
            AgentInstanceContext agentInstanceContext)
        {
            // determine whether create-named-window
            var isCreateWindow = optionalStatementDesc != null &&
                                 optionalStatementDesc.Lightweight.StatementContext.StatementInformationals
                                     .StatementType ==
                                 StatementType.CREATE_WINDOW;
            ContextControllerDetailKeyedItem foundPartition = null;

            if (!isCreateWindow) {
                if (filtersSpec.FilterForEventType.Metadata.TypeClass == EventTypeTypeClass.NAMED_WINDOW) {
                    String declaredAsName = FindNamedWindowDeclaredAsName(statements, filtersSpec.FilterForEventType.Metadata.Name);
                    foreach (ContextControllerDetailKeyedItem partitionItem in keyedSpec.Items) {
                        if (partitionItem.FilterSpecActivatable.FilterForEventType.Name.Equals(declaredAsName)) {
                            foundPartition = partitionItem;
                            break;
                        }
                    }
                }

                if (foundPartition == null) {
                    foreach (var partitionItem in keyedSpec.Items) {
                        var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(
                            filtersSpec.FilterForEventType,
                            partitionItem.FilterSpecActivatable.FilterForEventType);
                        if (typeOrSubtype) {
                            foundPartition = partitionItem;
                            break;
                        }
                    }
                }
            }
            else {
                var factory = (StatementAgentInstanceFactoryCreateNW) optionalStatementDesc.Lightweight.StatementContext
                    .StatementAIFactoryProvider
                    .Factory;
                var declaredAsName = factory.AsEventTypeName;
                foreach (var partitionItem in keyedSpec.Items) {
                    if (partitionItem.FilterSpecActivatable.FilterForEventType.Name.Equals(declaredAsName)) {
                        foundPartition = partitionItem;
                        break;
                    }
                }
            }

            if (foundPartition == null) {
                return null;
            }

            var lookupables = foundPartition.Lookupables;
            var addendumFilters = new FilterValueSetParam[lookupables.Length];
            if (lookupables.Length == 1) {
                addendumFilters[0] = GetFilterMayEqualOrNull(lookupables[0], getterKey);
            }
            else {
                var keyProvisioning = (MultiKey) getterKey;
                for (var i = 0; i < lookupables.Length; i++) {
                    addendumFilters[i] = GetFilterMayEqualOrNull(lookupables[i], keyProvisioning.GetKey(i));
                }
            }

            var addendum = new FilterValueSetParam[1][];
            addendum[0] = addendumFilters;

            var partitionFilters = foundPartition.FilterSpecActivatable.GetValueSet(
                null,
                null,
                agentInstanceContext,
                agentInstanceContext.StatementContextFilterEvalEnv);
            if (partitionFilters != null && includePartition) {
                addendum = FilterAddendumUtil.AddAddendum(partitionFilters, addendum[0]);
            }

            return addendum;
        }
コード例 #24
0
        public override CodegenExpression EvaluateGetCollEventsCodegen(
            CodegenMethodScope parent,
            ExprSubselectEvalMatchSymbol symbols,
            CodegenClassScope classScope)
        {
            if (subselect.FilterExpr == null) {
                if (subselect.SelectClause == null) {
                    return symbols.GetAddMatchingEvents(parent);
                }
                else {
                    if (subselect.subselectMultirowType == null) {
                        var eval = ((ExprIdentNode) subselect.SelectClause[0]).ExprEvaluatorIdent;
                        var method = parent.MakeChild(
                            typeof(FlexCollection),
                            this.GetType(),
                            classScope);
                        method.Block.DeclareVar<ICollection<EventBean>>(
                            "events",
                            NewInstance<ArrayDeque<EventBean>>(
                                ExprDotName(symbols.GetAddMatchingEvents(method), "Count")));
                        var @foreach = method.Block.ForEach(
                            typeof(EventBean),
                            "@event",
                            symbols.GetAddMatchingEvents(method));
                        {
                            @foreach.DeclareVar<EventBean>(
                                    "fragment",
                                    CodegenLegoCast.CastSafeFromObjectType(
                                        typeof(EventBean),
                                        eval.Getter.EventBeanFragmentCodegen(Ref("@event"), method, classScope)))
                                .IfRefNull("fragment")
                                .BlockContinue()
                                .ExprDotMethod(Ref("events"), "Add", Ref("fragment"));
                        }
                        method.Block.MethodReturn(FlexWrap(Ref("events")));
                        return LocalMethod(method);
                    }

                    // when selecting a combined output row that contains multiple fields
                    var methodX = parent.MakeChild(typeof(FlexCollection), this.GetType(), classScope);
                    var fieldEventType = classScope.AddDefaultFieldUnshared(
                        true,
                        typeof(EventType),
                        EventTypeUtility.ResolveTypeCodegen(
                            subselect.subselectMultirowType,
                            EPStatementInitServicesConstants.REF));
                    var eventBeanSvc =
                        classScope.AddOrGetDefaultFieldSharable(EventBeanTypedEventFactoryCodegenField.INSTANCE);

                    methodX.Block
                        .DeclareVar<ICollection<EventBean>>(
                            "result",
                            NewInstance<ArrayDeque<EventBean>>(
                                ExprDotName(symbols.GetAddMatchingEvents(methodX), "Count")))
                        .ApplyTri(DECLARE_EVENTS_SHIFTED, methodX, symbols);
                    var foreachX = methodX.Block.ForEach(
                        typeof(EventBean),
                        "@event",
                        symbols.GetAddMatchingEvents(methodX));
                    {
                        foreachX.AssignArrayElement(REF_EVENTS_SHIFTED, Constant(0), Ref("@event"))
                            .DeclareVar<IDictionary<string, object>>(
                                "row",
                                LocalMethod(
                                    subselect.EvaluateRowCodegen(methodX, classScope),
                                    REF_EVENTS_SHIFTED,
                                    ConstantTrue(),
                                    symbols.GetAddExprEvalCtx(methodX)))
                            .DeclareVar<EventBean>(
                                "rowEvent",
                                ExprDotMethod(eventBeanSvc, "AdapterForTypedMap", Ref("row"), fieldEventType))
                            .ExprDotMethod(Ref("result"), "Add", Ref("rowEvent"));
                    }
                    methodX.Block.MethodReturn(FlexWrap(Ref("result")));
                    return LocalMethod(methodX);
                }
            }

            if (subselect.SelectClause != null) {
                return ConstantNull();
            }

            // handle filtered
            var methodY = parent.MakeChild(typeof(FlexCollection), this.GetType(), classScope);

            methodY.Block.ApplyTri(DECLARE_EVENTS_SHIFTED, methodY, symbols);

            methodY.Block.DeclareVar<ArrayDeque<EventBean>>("filtered", ConstantNull());
            var foreachY = methodY.Block.ForEach(
                typeof(EventBean),
                "@event",
                symbols.GetAddMatchingEvents(methodY));
            {
                foreachY.AssignArrayElement(REF_EVENTS_SHIFTED, Constant(0), Ref("@event"));
                var filter = CodegenLegoMethodExpression.CodegenExpression(subselect.FilterExpr, methodY, classScope, true);
                CodegenLegoBooleanExpression.CodegenContinueIfNullOrNotPass(
                    foreachY,
                    typeof(bool?),
                    LocalMethod(
                        filter,
                        REF_EVENTS_SHIFTED,
                        symbols.GetAddIsNewData(methodY),
                        symbols.GetAddExprEvalCtx(methodY)));
                foreachY.IfCondition(EqualsNull(Ref("filtered")))
                    .AssignRef("filtered", NewInstance(typeof(ArrayDeque<EventBean>)))
                    .BlockEnd()
                    .ExprDotMethod(Ref("filtered"), "Add", Ref("@event"));
            }

            methodY.Block.MethodReturn(FlexWrap(Ref("filtered")));
            return LocalMethod(methodY);
        }
コード例 #25
0
        private ExprDotNodeForge GetPropertyPairEvaluator(
            ExprForge parameterForge,
            Pair<PropertyResolutionDescriptor, string> propertyInfoPair,
            ExprValidationContext validationContext)
        {
            var propertyName = propertyInfoPair.First.PropertyName;
            var propertyDesc = EventTypeUtility.GetNestablePropertyDescriptor(
                propertyInfoPair.First.StreamEventType,
                propertyName);
            if (propertyDesc == null || !propertyDesc.IsMapped && !propertyDesc.IsIndexed) {
                throw new ExprValidationException(
                    "Unknown single-row function, aggregation function or mapped or indexed property named '" +
                    propertyName +
                    "' could not be resolved");
            }

            var streamNum = propertyInfoPair.First.StreamNum;
            EventPropertyGetterMappedSPI mappedGetter = null;
            EventPropertyGetterIndexedSPI indexedGetter = null;

            var propertyType = typeof(object);
            if (propertyDesc.IsMapped) {
                if (parameterForge.EvaluationType != typeof(string)) {
                    throw new ExprValidationException(
                        "Parameter expression to mapped property '" +
                        propertyDesc.PropertyName +
                        "' is expected to return a string-type value but returns " +
                        parameterForge.EvaluationType.CleanName());
                }

                mappedGetter =
                    ((EventTypeSPI) propertyInfoPair.First.StreamEventType).GetGetterMappedSPI(
                        propertyInfoPair.First.PropertyName);
                if (mappedGetter == null) {
                    throw new ExprValidationException(
                        "Mapped property named '" + propertyName + "' failed to obtain getter-object");
                }
            }
            else {
                if (parameterForge.EvaluationType.GetBoxedType() != typeof(int?)) {
                    throw new ExprValidationException(
                        "Parameter expression to indexed property '" +
                        propertyDesc.PropertyName +
                        "' is expected to return a Integer-type value but returns " +
                        parameterForge.EvaluationType.CleanName());
                }

                indexedGetter =
                    ((EventTypeSPI) propertyInfoPair.First.StreamEventType).GetGetterIndexedSPI(
                        propertyInfoPair.First.PropertyName);
                if (indexedGetter == null) {
                    throw new ExprValidationException(
                        "Indexed property named '" + propertyName + "' failed to obtain getter-object");
                }
            }

            if (propertyDesc.PropertyComponentType != null) {
                propertyType = propertyDesc.PropertyComponentType.GetBoxedType();
            }

            return new ExprDotNodeForgePropertyExpr(
                this,
                validationContext.StatementName,
                propertyDesc.PropertyName,
                streamNum,
                parameterForge,
                propertyType,
                indexedGetter,
                mappedGetter);
        }
コード例 #26
0
        public override CodegenExpression EvaluateGetBeanCodegen(
            CodegenMethodScope parent,
            ExprSubselectEvalMatchSymbol symbols,
            CodegenClassScope classScope)
        {
            var method = parent.MakeChild(typeof(EventBean), this.GetType(), classScope);

            if (subselect.SelectClause == null) {
                if (subselect.FilterExpr == null) {
                    method
                        .Block
                        .IfCondition(
                            Relational(
                                ExprDotName(
                                    symbols.GetAddMatchingEvents(method),
                                    "Count"),
                                CodegenExpressionRelational.CodegenRelational.GT,
                                Constant(1)))
                        .BlockReturn(ConstantNull())
                        .ApplyTri(DECLARE_EVENTS_SHIFTED, method, symbols)
                        .MethodReturn(StaticMethod(typeof(EventBeanUtility), "GetNonemptyFirstEvent", symbols.GetAddMatchingEvents(method)));
                    return LocalMethod(method);
                }

                CodegenExpression filterX = ExprNodeUtilityCodegen.CodegenEvaluator(
                    subselect.FilterExpr,
                    method,
                    GetType(),
                    classScope);
                method
                    .Block
                    .ApplyTri(DECLARE_EVENTS_SHIFTED, method, symbols)
                    .DeclareVar(
                        typeof(EventBean),
                        "subSelectResult",
                        StaticMethod(
                            typeof(EventBeanUtility),
                            "EvaluateFilterExpectSingleMatch",
                            REF_EVENTS_SHIFTED,
                            symbols.GetAddIsNewData(method),
                            symbols.GetAddMatchingEvents(method),
                            symbols.GetAddExprEvalCtx(method),
                            filterX))
                    .MethodReturn(Ref("subSelectResult"));
                return LocalMethod(method);
            }

            var eventBeanSvc =
                classScope.AddOrGetDefaultFieldSharable(EventBeanTypedEventFactoryCodegenField.INSTANCE);
            var typeMember = classScope.AddDefaultFieldUnshared(
                true,
                typeof(EventType),
                EventTypeUtility.ResolveTypeCodegen(
                    subselect.subselectMultirowType,
                    EPStatementInitServicesConstants.REF));

            if (subselect.FilterExpr == null) {
                method.Block
                    .ApplyTri(DECLARE_EVENTS_SHIFTED, method, symbols)
                    .AssignArrayElement(
                        REF_EVENTS_SHIFTED,
                        Constant(0),
                        StaticMethod(
                            typeof(EventBeanUtility),
                            "GetNonemptyFirstEvent",
                            symbols.GetAddMatchingEvents(method)))
                    .DeclareVar<IDictionary<string, object>>(
                        "row",
                        LocalMethod(
                            subselect.EvaluateRowCodegen(method, classScope),
                            REF_EVENTS_SHIFTED,
                            ConstantTrue(),
                            symbols.GetAddExprEvalCtx(method)))
                    .DeclareVar<EventBean>(
                        "bean",
                        ExprDotMethod(eventBeanSvc, "AdapterForTypedMap", Ref("row"), typeMember))
                    .MethodReturn(Ref("bean"));
                return LocalMethod(method);
            }

            var filter = ExprNodeUtilityCodegen.CodegenEvaluator(
                subselect.FilterExpr,
                method,
                this.GetType(),
                classScope);
            method.Block
                .ApplyTri(DECLARE_EVENTS_SHIFTED, method, symbols)
                .DeclareVar<EventBean>(
                    "subSelectResult",
                    StaticMethod(
                        typeof(EventBeanUtility),
                        "EvaluateFilterExpectSingleMatch",
                        REF_EVENTS_SHIFTED,
                        symbols.GetAddIsNewData(method),
                        symbols.GetAddMatchingEvents(method),
                        symbols.GetAddExprEvalCtx(method),
                        filter))
                .IfRefNullReturnNull("subselectResult")
                .DeclareVar<IDictionary<string, object>>(
                    "row",
                    LocalMethod(
                        subselect.EvaluateRowCodegen(method, classScope),
                        REF_EVENTS_SHIFTED,
                        ConstantTrue(),
                        symbols.GetAddExprEvalCtx(method)))
                .DeclareVar<EventBean>(
                    "bean",
                    ExprDotMethod(eventBeanSvc, "AdapterForTypedMap", Ref("row"), typeMember))
                .MethodReturn(Ref("bean"));
            return LocalMethod(method);
        }
コード例 #27
0
        protected internal static void ValidateStatementForContext(
            string contextName,
            ContextControllerStatementBase statement,
            StatementSpecCompiledAnalyzerResult streamAnalysis,
            ICollection <EventType> itemEventTypes,
            NamedWindowMgmtService namedWindowMgmtService)
        {
            var filters = streamAnalysis.Filters;

            var isCreateWindow = statement.StatementSpec.CreateWindowDesc != null;

            // if no create-window: at least one of the filters must match one of the filters specified by the context
            if (!isCreateWindow)
            {
                foreach (var filter in filters)
                {
                    foreach (var itemEventType in itemEventTypes)
                    {
                        var stmtFilterType = filter.FilterForEventType;
                        if (stmtFilterType == itemEventType)
                        {
                            return;
                        }
                        if (EventTypeUtility.IsTypeOrSubTypeOf(stmtFilterType, itemEventType))
                        {
                            return;
                        }

                        NamedWindowProcessor processor = namedWindowMgmtService.GetProcessor(stmtFilterType.Name);
                        if (processor != null && processor.ContextName != null &&
                            processor.ContextName.Equals(contextName))
                        {
                            return;
                        }
                    }
                }

                if (!filters.IsEmpty())
                {
                    throw new ExprValidationException(
                              GetTypeValidationMessage(contextName, filters[0].FilterForEventType.Name));
                }
                return;
            }

            // validate create-window with column definition: not allowed, requires typed
            if (statement.StatementSpec.CreateWindowDesc.Columns != null &&
                statement.StatementSpec.CreateWindowDesc.Columns.Count > 0)
            {
                throw new ExprValidationException(
                          "Segmented context '" + contextName +
                          "' requires that named windows are associated to an existing event type and that the event type is listed among the partitions defined by the create-context statement");
            }

            // validate create-window declared type
            var declaredAsName = statement.StatementSpec.CreateWindowDesc.AsEventTypeName;

            if (declaredAsName != null)
            {
                if (itemEventTypes.Any(itemEventType => itemEventType.Name == declaredAsName))
                {
                    return;
                }

                throw new ExprValidationException(GetTypeValidationMessage(contextName, declaredAsName));
            }
        }
コード例 #28
0
        public override EnumForge GetEnumForge(StreamTypeService streamTypeService,
            string enumMethodUsedName,
            IList<ExprDotEvalParam> bodiesAndParameters,
            EventType inputEventType,
            Type collectionComponentType,
            int numStreamsIncoming,
            bool disablePropertyExpressionEventCollCache,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            var first = bodiesAndParameters[0];

            var enumSrc = ExprDotNodeUtility.GetEnumerationSource(
                first.Body,
                streamTypeService,
                true,
                disablePropertyExpressionEventCollCache,
                statementRawInfo,
                services);
            if (inputEventType != null) {
                TypeInfo = EPTypeHelper.CollectionOfEvents(inputEventType);
            }
            else {
                TypeInfo = EPTypeHelper.CollectionOfSingleValue(collectionComponentType, null);
            }

            if (inputEventType != null) {
                var setType = enumSrc.Enumeration == null
                    ? null
                    : enumSrc.Enumeration.GetEventTypeCollection(statementRawInfo, services);
                if (setType == null) {
                    var message = "Enumeration method '" +
                                     enumMethodUsedName +
                                     "' requires an expression yielding a " +
                                     "collection of events of type '" +
                                     inputEventType.Name +
                                     "' as input parameter";
                    throw new ExprValidationException(message);
                }

                if (setType != inputEventType) {
                    var isSubtype = EventTypeUtility.IsTypeOrSubTypeOf(setType, inputEventType);
                    if (!isSubtype) {
                        var message = "Enumeration method '" +
                                         enumMethodUsedName +
                                         "' expects event type '" +
                                         inputEventType.Name +
                                         "' but receives event type '" +
                                         setType.Name +
                                         "'";
                        throw new ExprValidationException(message);
                    }
                }
            }
            else {
                var setType = enumSrc.Enumeration?.ComponentTypeCollection;
                if (setType == null) {
                    var message = "Enumeration method '" +
                                     enumMethodUsedName +
                                     "' requires an expression yielding a " +
                                     "collection of values of type '" +
                                     collectionComponentType.CleanName() +
                                     "' as input parameter";
                    throw new ExprValidationException(message);
                }

                if (!TypeHelper.IsAssignmentCompatible(setType, collectionComponentType)) {
                    var message = "Enumeration method '" +
                                     enumMethodUsedName +
                                     "' expects scalar type '" +
                                     collectionComponentType.Name +
                                     "' but receives event type '" +
                                     setType.Name +
                                     "'";
                    throw new ExprValidationException(message);
                }
            }

            if (EnumMethodEnum == EnumMethodEnum.UNION) {
                return new EnumUnionForge(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null);
            }
            else if (EnumMethodEnum == EnumMethodEnum.INTERSECT) {
                return new EnumIntersectForge(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null);
            }
            else if (EnumMethodEnum == EnumMethodEnum.EXCEPT) {
                return new EnumExceptForge(numStreamsIncoming, enumSrc.Enumeration, inputEventType == null);
            }
            else {
                throw new ArgumentException("Invalid enumeration method for this factory: " + EnumMethodEnum);
            }
        }
コード例 #29
0
        protected internal static Type[] ValidateContextDesc(string contextName, ContextDetailPartitioned segmentedSpec)
        {
            if (segmentedSpec.Items.IsEmpty())
            {
                throw new ExprValidationException("Empty list of partition items");
            }

            // verify properties exist
            foreach (var item in segmentedSpec.Items)
            {
                var type = item.FilterSpecCompiled.FilterForEventType;
                foreach (var property in item.PropertyNames)
                {
                    var getter = type.GetGetter(property);
                    if (getter == null)
                    {
                        throw new ExprValidationException(
                                  "For context '" + contextName + "' property name '" + property + "' not found on type " +
                                  type.Name);
                    }
                }
            }

            // verify property number and types compatible
            ContextDetailPartitionItem firstItem = segmentedSpec.Items[0];

            if (segmentedSpec.Items.Count > 1)
            {
                // verify the same filter event type is only listed once

                for (var i = 0; i < segmentedSpec.Items.Count; i++)
                {
                    EventType compareTo = segmentedSpec.Items[i].FilterSpecCompiled.FilterForEventType;

                    for (var j = 0; j < segmentedSpec.Items.Count; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }

                        EventType compareFrom = segmentedSpec.Items[j].FilterSpecCompiled.FilterForEventType;
                        if (compareFrom == compareTo)
                        {
                            throw new ExprValidationException(
                                      "For context '" + contextName + "' the event type '" + compareFrom.Name +
                                      "' is listed twice");
                        }
                        if (EventTypeUtility.IsTypeOrSubTypeOf(compareFrom, compareTo) ||
                            EventTypeUtility.IsTypeOrSubTypeOf(compareTo, compareFrom))
                        {
                            throw new ExprValidationException(
                                      "For context '" + contextName + "' the event type '" + compareFrom.Name +
                                      "' is listed twice: Event type '" +
                                      compareFrom.Name + "' is a subtype or supertype of event type '" + compareTo.Name + "'");
                        }
                    }
                }

                // build property type information
                var names      = new string[firstItem.PropertyNames.Count];
                var types      = new Type[firstItem.PropertyNames.Count];
                var typesBoxed = new Type[firstItem.PropertyNames.Count];
                for (var i = 0; i < firstItem.PropertyNames.Count; i++)
                {
                    string property = firstItem.PropertyNames[i];
                    names[i]      = property;
                    types[i]      = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property);
                    typesBoxed[i] = types[i].GetBoxedType();
                }

                // compare property types and numbers
                for (var item = 1; item < segmentedSpec.Items.Count; item++)
                {
                    ContextDetailPartitionItem nextItem = segmentedSpec.Items[item];

                    // compare number of properties
                    if (nextItem.PropertyNames.Count != types.Length)
                    {
                        throw new ExprValidationException(
                                  "For context '" + contextName +
                                  "' expected the same number of property names for each event type, found " +
                                  types.Length + " properties for event type '" +
                                  firstItem.FilterSpecCompiled.FilterForEventType.Name +
                                  "' and " + nextItem.PropertyNames.Count + " properties for event type '" +
                                  nextItem.FilterSpecCompiled.FilterForEventType.Name + "'");
                    }

                    // compare property types
                    for (var i = 0; i < nextItem.PropertyNames.Count; i++)
                    {
                        string property  = nextItem.PropertyNames[i];
                        var    type      = nextItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property).GetBoxedType();
                        var    typeBoxed = type.GetBoxedType();
                        var    left      = TypeHelper.IsSubclassOrImplementsInterface(typeBoxed, typesBoxed[i]);
                        var    right     = TypeHelper.IsSubclassOrImplementsInterface(typesBoxed[i], typeBoxed);
                        if (typeBoxed != typesBoxed[i] && !left && !right)
                        {
                            throw new ExprValidationException(
                                      "For context '" + contextName + "' for context '" + contextName +
                                      "' found mismatch of property types, property '" + names[i] +
                                      "' of type '" + types[i].GetTypeNameFullyQualPretty() +
                                      "' compared to property '" + property +
                                      "' of type '" + typeBoxed.GetTypeNameFullyQualPretty() + "'");
                        }
                    }
                }
            }

            var propertyTypes = new Type[firstItem.PropertyNames.Count];

            for (var i = 0; i < firstItem.PropertyNames.Count; i++)
            {
                string property = firstItem.PropertyNames[i];
                propertyTypes[i] = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property);
            }
            return(propertyTypes);
        }
コード例 #30
0
        public static PropertyEvaluatorForge MakeEvaluator(
            PropertyEvalSpec spec,
            EventType sourceEventType,
            string optionalSourceStreamName,
            StatementRawInfo rawInfo,
            StatementCompileTimeServices services)
        {
            var length = spec.Atoms.Count;
            var containedEventForges = new ContainedEventEvalForge[length];
            var fragmentEventTypes = new FragmentEventType[length];
            var currentEventType = sourceEventType;
            var whereClauses = new ExprForge[length];

            IList<EventType> streamEventTypes = new List<EventType>();
            IList<string> streamNames = new List<string>();
            IDictionary<string, int> streamNameAndNumber = new Dictionary<string, int>().WithNullKeySupport();
            IList<string> expressionTexts = new List<string>();

            streamEventTypes.Add(sourceEventType);
            streamNames.Add(optionalSourceStreamName);
            streamNameAndNumber.Put(optionalSourceStreamName, 0);
            expressionTexts.Add(sourceEventType.Name);

            IList<SelectClauseElementCompiled> cumulativeSelectClause = new List<SelectClauseElementCompiled>();
            for (var i = 0; i < length; i++) {
                var atom = spec.Atoms[i];
                ContainedEventEvalForge containedEventEval = null;
                string expressionText = null;
                EventType streamEventType = null;
                FragmentEventType fragmentEventType = null;

                // Resolve directly as fragment event type if possible
                if (atom.SplitterExpression is ExprIdentNode) {
                    var propertyName = ((ExprIdentNode) atom.SplitterExpression).FullUnresolvedName;
                    fragmentEventType = currentEventType.GetFragmentType(propertyName);
                    if (fragmentEventType != null) {
                        var getter = ((EventTypeSPI) currentEventType).GetGetterSPI(propertyName);
                        if (getter != null) {
                            containedEventEval = new ContainedEventEvalGetterForge(getter);
                            expressionText = propertyName;
                            streamEventType = fragmentEventType.FragmentType;
                        }
                    }
                }

                // evaluate splitter expression
                if (containedEventEval == null) {
                    ExprNodeUtilityValidate.ValidatePlainExpression(
                        ExprNodeOrigin.CONTAINEDEVENT,
                        atom.SplitterExpression);

                    var availableTypes = streamEventTypes.ToArray();
                    var availableStreamNames = streamNames.ToArray();
                    var isIStreamOnly = new bool[streamNames.Count];
                    isIStreamOnly.Fill(true);
                    StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                        availableTypes,
                        availableStreamNames,
                        isIStreamOnly,
                        false,
                        false);
                    var validationContext = new ExprValidationContextBuilder(streamTypeService, rawInfo, services)
                        .WithAllowBindingConsumption(true)
                        .Build();
                    var validatedExprNode = ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.CONTAINEDEVENT,
                        atom.SplitterExpression,
                        validationContext);

                    // determine result type
                    if (atom.OptionalResultEventType == null) {
                        throw new ExprValidationException(
                            "Missing @type(name) declaration providing the event type name of the return type for expression '" +
                            ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) +
                            "'");
                    }

                    streamEventType = services.EventTypeCompileTimeResolver.GetTypeByName(atom.OptionalResultEventType);
                    if (streamEventType == null) {
                        throw new ExprValidationException(
                            "Event type by name '" + atom.OptionalResultEventType + "' could not be found");
                    }

                    var returnType = validatedExprNode.Forge.EvaluationType;

                    // when the expression returns an array, allow array values to become the column of the single-column event type
                    if (returnType.IsArray &&
                        streamEventType.PropertyNames.Length == 1 &&
                        TypeHelper.IsSubclassOrImplementsInterface(
                            returnType.GetElementType().GetBoxedType(),
                            streamEventType.GetPropertyType(streamEventType.PropertyNames[0]).GetBoxedType())) {
                        var writables = EventTypeUtility.GetWriteableProperties(streamEventType, false);
                        if (writables != null && !writables.IsEmpty()) {
                            try {
                                var manufacturer = EventTypeUtility.GetManufacturer(
                                    streamEventType,
                                    new[] {writables.First()},
                                    services.ImportServiceCompileTime,
                                    false,
                                    services.EventTypeAvroHandler);
                                containedEventEval = new ContainedEventEvalArrayToEventForge(
                                    validatedExprNode.Forge,
                                    manufacturer);
                            }
                            catch (EventBeanManufactureException e) {
                                throw new ExprValidationException(
                                    "Event type '" + streamEventType.Name + "' cannot be populated: " + e.Message,
                                    e);
                            }
                        }
                        else {
                            throw new ExprValidationException(
                                "Event type '" + streamEventType.Name + "' cannot be written to");
                        }
                    }
                    else if (returnType.IsArray &&
                             returnType.GetElementType() == typeof(EventBean)) {
                        containedEventEval = new ContainedEventEvalEventBeanArrayForge(validatedExprNode.Forge);
                    }
                    else {
                        // check expression result type against eventtype expected underlying type
                        if (returnType.IsArray) {
                            if (!TypeHelper.IsSubclassOrImplementsInterface(
                                returnType.GetElementType(),
                                streamEventType.UnderlyingType)) {
                                throw new ExprValidationException(
                                    "Event type '" +
                                    streamEventType.Name +
                                    "' underlying type " +
                                    streamEventType.UnderlyingType.Name +
                                    " cannot be assigned a value of type " +
                                    returnType.CleanName());
                            }
                        }
                        else if (returnType.IsGenericEnumerable()) {
                            // fine, assumed to return the right type
                        }
                        else {
                            throw new ExprValidationException(
                                "Return type of expression '" +
                                ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) +
                                "' is '" +
                                returnType.Name +
                                "', expected an Iterable or array result");
                        }

                        containedEventEval = new ContainedEventEvalExprNodeForge(
                            validatedExprNode.Forge,
                            streamEventType);
                    }

                    expressionText = ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(validatedExprNode);
                    fragmentEventType = new FragmentEventType(streamEventType, true, false);
                }

                // validate where clause, if any
                streamEventTypes.Add(streamEventType);
                streamNames.Add(atom.OptionalAsName);
                streamNameAndNumber.Put(atom.OptionalAsName, i + 1);
                expressionTexts.Add(expressionText);

                if (atom.OptionalWhereClause != null) {
                    var whereTypes = streamEventTypes.ToArray();
                    var whereStreamNames = streamNames.ToArray();
                    var isIStreamOnly = new bool[streamNames.Count];
                    isIStreamOnly.Fill(true);
                    StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                        whereTypes,
                        whereStreamNames,
                        isIStreamOnly,
                        false,
                        false);
                    var validationContext = new ExprValidationContextBuilder(streamTypeService, rawInfo, services)
                        .WithAllowBindingConsumption(true)
                        .Build();
                    var whereClause = ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.CONTAINEDEVENT,
                        atom.OptionalWhereClause,
                        validationContext);
                    whereClauses[i] = whereClause.Forge;
                }

                // validate select clause
                if (atom.OptionalSelectClause != null && !atom.OptionalSelectClause.SelectExprList.IsEmpty()) {
                    var whereTypes = streamEventTypes.ToArray();
                    var whereStreamNames = streamNames.ToArray();
                    var isIStreamOnly = new bool[streamNames.Count];
                    isIStreamOnly.Fill(true);
                    StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                        whereTypes,
                        whereStreamNames,
                        isIStreamOnly,
                        false,
                        false);
                    var validationContext = new ExprValidationContextBuilder(streamTypeService, rawInfo, services)
                        .WithAllowBindingConsumption(true)
                        .Build();

                    foreach (var raw in atom.OptionalSelectClause.SelectExprList) {
                        if (raw is SelectClauseStreamRawSpec) {
                            var rawStreamSpec = (SelectClauseStreamRawSpec) raw;
                            if (!streamNames.Contains(rawStreamSpec.StreamName)) {
                                throw new ExprValidationException(
                                    "Property rename '" + rawStreamSpec.StreamName + "' not found in path");
                            }

                            var streamSpec = new SelectClauseStreamCompiledSpec(
                                rawStreamSpec.StreamName,
                                rawStreamSpec.OptionalAsName);
                            var streamNumber = streamNameAndNumber.Get(rawStreamSpec.StreamName);
                            streamSpec.StreamNumber = streamNumber;
                            cumulativeSelectClause.Add(streamSpec);
                        }
                        else if (raw is SelectClauseExprRawSpec) {
                            var exprSpec = (SelectClauseExprRawSpec) raw;
                            var exprCompiled = ExprNodeUtilityValidate.GetValidatedSubtree(
                                ExprNodeOrigin.CONTAINEDEVENT,
                                exprSpec.SelectExpression,
                                validationContext);
                            var resultName = exprSpec.OptionalAsName;
                            if (resultName == null) {
                                resultName = ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(exprCompiled);
                            }

                            cumulativeSelectClause.Add(
                                new SelectClauseExprCompiledSpec(
                                    exprCompiled,
                                    resultName,
                                    exprSpec.OptionalAsName,
                                    exprSpec.IsEvents));

                            var isMinimal = ExprNodeUtilityValidate.IsMinimalExpression(exprCompiled);
                            if (isMinimal != null) {
                                throw new ExprValidationException(
                                    "Expression in a property-selection may not utilize " + isMinimal);
                            }
                        }
                        else if (raw is SelectClauseElementWildcard) {
                            // wildcards are stream selects: we assign a stream name (any) and add a stream wildcard select
                            var streamNameAtom = atom.OptionalAsName;
                            if (streamNameAtom == null) {
                                streamNameAtom = UuidGenerator.Generate();
                            }

                            var streamSpec = new SelectClauseStreamCompiledSpec(streamNameAtom, atom.OptionalAsName);
                            var streamNumber = i + 1;
                            streamSpec.StreamNumber = streamNumber;
                            cumulativeSelectClause.Add(streamSpec);
                        }
                        else {
                            throw new IllegalStateException("Unknown select clause item:" + raw);
                        }
                    }
                }

                currentEventType = fragmentEventType.FragmentType;
                fragmentEventTypes[i] = fragmentEventType;
                containedEventForges[i] = containedEventEval;
            }

            if (cumulativeSelectClause.IsEmpty()) {
                if (length == 1) {
                    return new PropertyEvaluatorSimpleForge(
                        containedEventForges[0],
                        fragmentEventTypes[0],
                        whereClauses[0],
                        expressionTexts[0]);
                }

                return new PropertyEvaluatorNestedForge(
                    containedEventForges,
                    fragmentEventTypes,
                    whereClauses,
                    expressionTexts.ToArray());
            }

            {
                var fragmentEventTypeIsIndexed = new bool[fragmentEventTypes.Length];
                for (var i = 0; i < fragmentEventTypes.Length; i++) {
                    fragmentEventTypeIsIndexed[i] = fragmentEventTypes[i].IsIndexed;
                }

                var accumulative = new PropertyEvaluatorAccumulativeForge(
                    containedEventForges,
                    fragmentEventTypeIsIndexed,
                    whereClauses,
                    expressionTexts);

                var whereTypes = streamEventTypes.ToArray();
                var whereStreamNames = streamNames.ToArray();
                var isIStreamOnly = new bool[streamNames.Count];
                isIStreamOnly.Fill(true);
                StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                    whereTypes,
                    whereStreamNames,
                    isIStreamOnly,
                    false,
                    false);

                var cumulativeSelectArr = cumulativeSelectClause.ToArray();
                var args = new SelectProcessorArgs(
                    cumulativeSelectArr,
                    null,
                    false,
                    null,
                    null,
                    streamTypeService,
                    null,
                    false,
                    rawInfo.Annotations,
                    rawInfo,
                    services);
                var selectExprDesc = SelectExprProcessorFactory.GetProcessor(args, null, false);

                return new PropertyEvaluatorSelectForge(selectExprDesc, accumulative);
            }
        }