Пример #1
0
        public override AggregationMethodFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            const string message          = "The nth aggregation function requires two parameters, an expression returning aggregation values and a numeric index constant";
            var          positionalParams = PositionalParams;

            if (positionalParams.Length != 2)
            {
                throw new ExprValidationException(message);
            }

            ExprNode first  = positionalParams[0];
            ExprNode second = positionalParams[1];

            if (!second.IsConstantResult)
            {
                throw new ExprValidationException(message);
            }

            var num  = second.ExprEvaluator.Evaluate(new EvaluateParams(null, true, validationContext.ExprEvaluatorContext));
            int size = num.AsInt();

            return(new ExprNthAggNodeFactory(this, first.ExprEvaluator.ReturnType, size));
        }
Пример #2
0
 private static ExprNodeUtilMethodDesc GetValidateMethodDescriptor(
     Type methodTarget,
     string methodName,
     IList<ExprNode> parameters,
     ExprValidationContext validationContext)
 {
     ExprNodeUtilResolveExceptionHandler exceptionHandler = new ProxyExprNodeUtilResolveExceptionHandler(
         e => new ExprValidationException("Failed to resolve method '" + methodName + "': " + e.Message, e));
     var wildcardType = validationContext.StreamTypeService.EventTypes.Length != 1
         ? null
         : validationContext.StreamTypeService.EventTypes[0];
     return ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
         methodTarget.FullName,
         methodTarget,
         methodName,
         parameters,
         wildcardType != null,
         wildcardType,
         exceptionHandler,
         methodName,
         validationContext.StatementRawInfo,
         validationContext.StatementCompileTimeService);
 }
Пример #3
0
        public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            string message =
                "The nth aggregation function requires two parameters, an expression returning aggregation values and a numeric index constant";
            if (this.positionalParams.Length != 2) {
                throw new ExprValidationException(message);
            }

            ExprNode first = this.positionalParams[0];
            ExprNode second = this.positionalParams[1];
            if (!second.Forge.ForgeConstantType.IsCompileTimeConstant) {
                throw new ExprValidationException(message);
            }

            var num = second.Forge.ExprEvaluator.Evaluate(null, true, null);
            int size = num.AsInt32();

            if (optionalFilter != null) {
                this.positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter);
            }

            return new AggregationFactoryMethodNth(this, first.Forge.EvaluationType, size);
        }
Пример #4
0
        public void SetObserverParameters(
            IList<ExprNode> parameters,
            MatchedEventConvertorForge convertor,
            ExprValidationContext validationContext)
        {
            ObserverParameterUtil.ValidateNoNamedParameters("timer:at", parameters);
            if (Log.IsDebugEnabled) {
                Log.Debug(".setObserverParameters " + parameters);
            }

            if (parameters.Count < 5 || parameters.Count > 9) {
                throw new ObserverParameterException("Invalid number of parameters for timer:at");
            }

            this.parameters = parameters;
            this.convertor = convertor;

            // if all parameters are constants, lets try to evaluate and build a schedule for early validation
            var allConstantResult = true;
            foreach (var param in parameters) {
                if (!(param is ExprWildcard) && !param.Forge.ForgeConstantType.IsCompileTimeConstant) {
                    allConstantResult = false;
                }
            }

            if (allConstantResult) {
                try {
                    var observerParameters = EvaluateCompileTime(parameters);
                    spec = ScheduleSpecUtil.ComputeValues(observerParameters.ToArray());
                }
                catch (ScheduleParameterException e) {
                    throw new ObserverParameterException(
                        "Error computing crontab schedule specification: " + e.Message,
                        e);
                }
            }
        }
Пример #5
0
        protected override AggregationMethodFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            if (PositionalParams.Length > 2 || PositionalParams.Length == 0)
            {
                throw MakeExceptionExpectedParamNum(1, 2);
            }

            Type childType   = null;
            bool ignoreNulls = false;

            if (PositionalParams.Length == 1 && PositionalParams[0] is ExprWildcard)
            {
                ValidateNotDistinct();
                // defaults
            }
            else if (PositionalParams.Length == 1)
            {
                childType   = PositionalParams[0].ExprEvaluator.ReturnType;
                ignoreNulls = true;
            }
            else if (PositionalParams.Length == 2)
            {
                _hasFilter = true;
                if (!(PositionalParams[0] is ExprWildcard))
                {
                    childType   = PositionalParams[0].ExprEvaluator.ReturnType;
                    ignoreNulls = true;
                }
                else
                {
                    ValidateNotDistinct();
                }
                base.ValidateFilter(PositionalParams[1].ExprEvaluator);
            }

            return(validationContext.EngineImportService.AggregationFactoryFactory.MakeCount(validationContext.StatementExtensionSvcContext, this, ignoreNulls, childType));
        }
Пример #6
0
 private ExprNode ValidateMeasureClause(
     ExprNode measureNode,
     StreamTypeService typeServiceMeasure,
     ISet <string> variablesMultiple,
     ISet <string> variablesSingle,
     StatementContext statementContext)
 {
     try
     {
         var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false);
         var validationContext    = new ExprValidationContext(
             typeServiceMeasure,
             statementContext.EngineImportService,
             statementContext.StatementExtensionServicesContext, null,
             statementContext.SchedulingService,
             statementContext.VariableService, statementContext.TableService, exprEvaluatorContext,
             statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId,
             statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService,
             false, false, true, false, null, false);
         return(ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGMEASURE, measureNode, validationContext));
     }
     catch (ExprValidationPropertyException e)
     {
         var grouped = CollectionUtil.ToString(variablesMultiple);
         var single  = CollectionUtil.ToString(variablesSingle);
         var message = e.Message;
         if (!variablesMultiple.IsEmpty())
         {
             message += ", ensure that grouped variables (variables " + grouped + ") are accessed via index (i.e. variable[0].property) or appear within an aggregation";
         }
         if (!variablesSingle.IsEmpty())
         {
             message += ", ensure that singleton variables (variables " + single + ") are not accessed via index";
         }
         throw new ExprValidationPropertyException(message, e);
     }
 }
        private LinearAggregationFactoryDesc HandleIntoTable(
            ExprNode[] childNodes,
            AggregationStateType stateType,
            ExprValidationContext validationContext)
        {
            var message = "For into-table use 'window(*)' or ''window(stream.*)' instead";
            if (stateType != AggregationStateType.WINDOW) throw new ExprValidationException(message);
            if (childNodes.Length == 0 || childNodes.Length > 1) throw new ExprValidationException(message);
            if (validationContext.StreamTypeService.StreamNames.Length == 0)
                throw new ExprValidationException(GetErrorPrefix(stateType) +
                                                  " requires that at least one stream is provided");
            int streamNum;
            if (childNodes[0] is ExprWildcard)
            {
                if (validationContext.StreamTypeService.StreamNames.Length != 1)
                    throw new ExprValidationException(GetErrorPrefix(stateType) +
                                                      " with wildcard requires a single stream");
                streamNum = 0;
            }
            else if (childNodes[0] is ExprStreamUnderlyingNode)
            {
                var und = (ExprStreamUnderlyingNode) childNodes[0];
                streamNum = und.StreamId;
            }
            else
            {
                throw new ExprValidationException(message);
            }

            var containedType = validationContext.StreamTypeService.EventTypes[streamNum];
            var componentType = containedType.UnderlyingType;
            var accessor = new AggregationAccessorWindowNoEval(componentType);
            var agent = ExprAggAggregationAgentFactory.Make(streamNum, OptionalFilter);
            var factory = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(this, accessor,
                TypeHelper.GetArrayType(componentType), containedType, null, null, agent);
            return new LinearAggregationFactoryDesc(factory, factory.ContainedEventType, null);
        }
Пример #8
0
        public override AggregationMethodFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            if (PositionalParams.Length > 2 || PositionalParams.Length == 0)
            {
                throw MakeExceptionExpectedParamNum(1, 2);
            }

            Type childType   = null;
            bool ignoreNulls = false;

            if (PositionalParams.Length == 1 && PositionalParams[0] is ExprWildcard)
            {
                ValidateNotDistinct();
                // defaults
            }
            else if (PositionalParams.Length == 1)
            {
                childType   = PositionalParams[0].ExprEvaluator.ReturnType;
                ignoreNulls = true;
            }
            else if (PositionalParams.Length == 2)
            {
                _hasFilter = true;
                if (!(PositionalParams[0] is ExprWildcard))
                {
                    childType   = PositionalParams[0].ExprEvaluator.ReturnType;
                    ignoreNulls = true;
                }
                else
                {
                    ValidateNotDistinct();
                }
                base.ValidateFilter(PositionalParams[1].ExprEvaluator);
            }

            return(new ExprCountNodeFactory(this, ignoreNulls, childType));
        }
Пример #9
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (ChildNodes.Length != 1) {
                throw new ExprValidationException(
                    "Typeof node must have 1 child expression node supplying the expression to test");
            }

            if (ChildNodes[0] is ExprStreamUnderlyingNode) {
                var stream = (ExprStreamUnderlyingNode) ChildNodes[0];
                forge = new ExprTypeofNodeForgeStreamEvent(this, stream.StreamId);
                return null;
            }

            if (ChildNodes[0] is ExprIdentNode) {
                var ident = (ExprIdentNode) ChildNodes[0];
                var streamNum = validationContext.StreamTypeService.GetStreamNumForStreamName(ident.FullUnresolvedName);
                if (streamNum != -1) {
                    forge = new ExprTypeofNodeForgeStreamEvent(this, streamNum);
                    return null;
                }

                var eventType = validationContext.StreamTypeService.EventTypes[ident.StreamId];
                var fragmentEventType = eventType.GetFragmentType(ident.ResolvedPropertyName);
                if (fragmentEventType != null) {
                    var getter = ((EventTypeSPI) eventType).GetGetterSPI(ident.ResolvedPropertyName);
                    forge = new ExprTypeofNodeForgeFragmentType(
                        this,
                        ident.StreamId,
                        getter,
                        fragmentEventType.FragmentType.Name);
                    return null;
                }
            }

            forge = new ExprTypeofNodeForgeInnerEval(this);
            return null;
        }
Пример #10
0
        /// <summary>
        /// Validates the date format.
        /// </summary>
        /// <param name="dateFormatParameter">The date format parameter.</param>
        /// <param name="validationContext">The validation context.</param>
        /// <returns></returns>

        private ExprCastNodeDateDesc ValidateDateFormat(
            ExprNamedParameterNode dateFormatParameter,
            ExprValidationContext validationContext)
        {
            string        staticDateFormat  = null;
            ExprEvaluator dynamicDateFormat = null;
            var           iso8601Format     = false;

            if (!dateFormatParameter.ChildNodes[0].IsConstantResult)
            {
                dynamicDateFormat = dateFormatParameter.ChildNodes[0].ExprEvaluator;
            }
            else
            {
                staticDateFormat = (string)dateFormatParameter.ChildNodes[0].ExprEvaluator.Evaluate(
                    new EvaluateParams(null, true, validationContext.ExprEvaluatorContext));
                if (staticDateFormat.ToLowerInvariant().Trim().Equals("iso"))
                {
                    iso8601Format = true;
                }
                else
                {
                    try
                    {
                        DateTime dateTimeTemp;
                        DateTime.TryParseExact("", staticDateFormat, null, DateTimeStyles.None, out dateTimeTemp);
                        //new SimpleDateFormat(staticDateFormat);
                    }
                    catch (Exception ex)
                    {
                        throw new ExprValidationException(
                                  "Invalid date format '" + staticDateFormat + "': " + ex.Message, ex);
                    }
                }
            }
            return(new ExprCastNodeDateDesc(staticDateFormat, dynamicDateFormat, iso8601Format));
        }
Пример #11
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (validationContext.TableService == null || !validationContext.IsAllowBindingConsumption)
            {
                throw new ExprValidationException("Invalid use of table access expression, expression '" + _tableName + "' is not allowed here");
            }
            TableMetadata metadata = validationContext.TableService.GetTableMetadata(_tableName);

            if (metadata == null)
            {
                throw new ExprValidationException("A table '" + _tableName + "' could not be found");
            }

            if (metadata.ContextName != null &&
                validationContext.ContextDescriptor != null &&
                !metadata.ContextName.Equals(validationContext.ContextDescriptor.ContextName))
            {
                throw new ExprValidationException("Table by name '" + _tableName + "' has been declared for context '" + metadata.ContextName + "' and can only be used within the same context");
            }

            // additional validations depend on detail
            ValidateBindingInternal(validationContext, metadata);
            return(null);
        }
Пример #12
0
        public void SetObserverParameters(
            IList <ExprNode> parameters,
            MatchedEventConvertor convertor,
            ExprValidationContext validationContext)
        {
            ObserverParameterUtil.ValidateNoNamedParameters(NAME, parameters);
            const string errorMessage = NAME + " requires a single numeric or time period parameter";

            if (parameters.Count != 1)
            {
                throw new ObserverParameterException(errorMessage);
            }
            if (!(parameters[0] is ExprTimePeriod))
            {
                var returnType = parameters[0].ExprEvaluator.ReturnType;
                if (!returnType.IsNumeric())
                {
                    throw new ObserverParameterException(errorMessage);
                }
            }

            _parameter = parameters[0];
            _convertor = convertor;
        }
        private LinearAggregationFactoryDesc HandleTableAccessWindow(
            ExprNode[] childNodes,
            AggregationStateType stateType,
            ExprValidationContext validationContext,
            TableMetadataColumnAggregation tableAccess)
        {
            var original = (ExprAggMultiFunctionLinearAccessNodeFactoryAccess)tableAccess.Factory;

            if (childNodes.Length == 0 ||
                (childNodes.Length == 1 && childNodes[0] is ExprWildcard))
            {
                var componentType = original.ContainedEventType.UnderlyingType;
                var accessor      = new AggregationAccessorWindowNoEval(componentType);
                var factory       = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(
                    this, accessor, TypeHelper.GetArrayType(componentType), original.ContainedEventType, null, null,
                    null);
                return(new LinearAggregationFactoryDesc(factory, factory.ContainedEventType, null));
            }
            if (childNodes.Length == 1)
            {
                // Expressions apply to events held, thereby validate in terms of event value expressions
                var paramNode = childNodes[0];
                var streams   = TableServiceUtil.StreamTypeFromTableColumn(
                    tableAccess, validationContext.StreamTypeService.EngineURIQualifier);
                var localValidationContext = new ExprValidationContext(streams, validationContext);
                paramNode = ExprNodeUtility.GetValidatedSubtree(
                    ExprNodeOrigin.AGGPARAM, paramNode, localValidationContext);
                var paramNodeEval = paramNode.ExprEvaluator;
                var factory       = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(
                    this,
                    new AggregationAccessorWindowWEval(0, paramNodeEval, paramNodeEval.ReturnType),
                    TypeHelper.GetArrayType(paramNodeEval.ReturnType), original.ContainedEventType, null, null, null);
                return(new LinearAggregationFactoryDesc(factory, null, paramNodeEval.ReturnType));
            }
            throw new ExprValidationException("Invalid number of parameters");
        }
        public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            AggregationForgeFactoryAccessSorted factory;

            if (validationContext.StatementRawInfo.StatementType == StatementType.CREATE_TABLE)
            {
                // handle create-table statements (state creator and default accessor, limited to certain options)
                factory = HandleCreateTable(validationContext);
            }
            else if (validationContext.StatementRawInfo.IntoTableName != null)
            {
                // handle into-table (state provided, accessor and agent needed, validation done by factory)
                factory = HandleIntoTable(validationContext);
            }
            else
            {
                // handle standalone
                factory = HandleNonTable(validationContext);
            }

            _containedType           = factory.ContainedEventType;
            _aggregationForgeFactory = factory;
            return(factory);
        }
Пример #15
0
        public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            if (positionalParams.Length > 2) {
                throw MakeExceptionExpectedParamNum(0, 2);
            }

            if (positionalParams.Length == 2) {
                ValidateFilter(positionalParams[1]);
                optionalFilter = positionalParams[1];
            }

            Type resultType;
            var isWildcard = positionalParams.Length == 0 ||
                             positionalParams.Length > 0 && positionalParams[0] is ExprWildcard;
            if (isWildcard) {
                resultType = validationContext.StreamTypeService.EventTypes[0].UnderlyingType;
            }
            else {
                resultType = positionalParams[0].Forge.EvaluationType;
            }

            var serde = validationContext.SerdeResolver.SerdeForAggregation(resultType, validationContext.StatementRawInfo);
            return new AggregationForgeFactoryFirstLastEver(this, resultType, serde);
        }
Пример #16
0
        public override AggregationMethodFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            if (PositionalParams.Length == 0 || PositionalParams.Length > 2)
            {
                throw new ExprValidationException(_minMaxTypeEnum.ToString() + " node must have either 1 or 2 parameters");
            }

            ExprNode child = PositionalParams[0];
            bool     hasDataWindows;

            if (_isEver)
            {
                hasDataWindows = false;
            }
            else
            {
                if (validationContext.ExprEvaluatorContext.StatementType == StatementType.CREATE_TABLE)
                {
                    hasDataWindows = true;
                }
                else
                {
                    hasDataWindows = ExprNodeUtility.HasRemoveStreamForAggregations(child, validationContext.StreamTypeService, validationContext.IsResettingAggregations);
                }
            }

            if (_hasFilter)
            {
                if (PositionalParams.Length < 2)
                {
                    throw new ExprValidationException(_minMaxTypeEnum.ToString() + "-filtered aggregation function must have a filter expression as a second parameter");
                }
                base.ValidateFilter(PositionalParams[1].ExprEvaluator);
            }
            return(new ExprMinMaxAggrNodeFactory(this, child.ExprEvaluator.ReturnType, hasDataWindows));
        }
Пример #17
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (this.ChildNodes.Length != 2)
            {
                throw new ExprValidationException(NAME + "requires two parameters");
            }

            ExprStreamUnderlyingNode undOne = CheckStreamUnd(this.ChildNodes[0]);
            ExprStreamUnderlyingNode undTwo = CheckStreamUnd(this.ChildNodes[1]);

            if (undOne.EventType != undTwo.EventType)
            {
                throw new ExprValidationException(
                          NAME +
                          " received two different event types as parameter, type '" +
                          undOne.EventType.Name +
                          "' is not the same as type '" +
                          undTwo.EventType.Name +
                          "'");
            }

            forge = new ExprEventIdentityEqualsNodeForge(this, undOne, undTwo);
            return(null);
        }
Пример #18
0
        public void SetObserverParameters(IList<ExprNode> parameters, MatchedEventConvertor convertor, ExprValidationContext validationContext)
        {
            Convertor = convertor;

            // obtains name parameters
            IDictionary<string, ExprNamedParameterNode> namedExpressions;
            try
            {
                namedExpressions = ExprNodeUtility.GetNamedExpressionsHandleDups(parameters);
                ExprNodeUtility.ValidateNamed(namedExpressions, NAMED_PARAMETERS);
            }
            catch (ExprValidationException e)
            {
                throw new ObserverParameterException(e.Message, e);
            }

            bool allConstantResult;
            ExprNamedParameterNode isoStringExpr = namedExpressions.Get(ISO_NAME);
            if (namedExpressions.Count == 1 && isoStringExpr != null)
            {
                try
                {
                    allConstantResult = ExprNodeUtility.ValidateNamedExpectType(
                        isoStringExpr, new Type[]
                        {
                            typeof (string)
                        });
                }
                catch (ExprValidationException ex)
                {
                    throw new ObserverParameterException(ex.Message, ex);
                }
                ScheduleComputer = new TimerScheduleSpecComputeISOString(isoStringExpr.ChildNodes[0]);
            }
            else if (isoStringExpr != null)
            {
                throw new ObserverParameterException(
                    "The '" + ISO_NAME + "' parameter is exclusive of other parameters");
            }
            else if (namedExpressions.Count == 0)
            {
                throw new ObserverParameterException("No parameters provided");
            }
            else
            {
                allConstantResult = true;
                ExprNamedParameterNode dateNamedNode = namedExpressions.Get(DATE_NAME);
                ExprNamedParameterNode repetitionsNamedNode = namedExpressions.Get(REPETITIONS_NAME);
                ExprNamedParameterNode periodNamedNode = namedExpressions.Get(PERIOD_NAME);
                if (dateNamedNode == null && periodNamedNode == null)
                {
                    throw new ObserverParameterException("Either the date or period parameter is required");
                }
                try
                {
                    if (dateNamedNode != null)
                    {
                        allConstantResult = ExprNodeUtility.ValidateNamedExpectType(
                            dateNamedNode, new Type[]
                            {
                                typeof (string),
                                typeof (DateTime),
                                typeof (DateTimeOffset),
                                typeof (long?)
                            });
                    }
                    if (repetitionsNamedNode != null)
                    {
                        allConstantResult &= ExprNodeUtility.ValidateNamedExpectType(
                            repetitionsNamedNode, new Type[]
                            {
                                typeof (int?),
                                typeof (long?)
                            });
                    }
                    if (periodNamedNode != null)
                    {
                        allConstantResult &= ExprNodeUtility.ValidateNamedExpectType(
                            periodNamedNode, new Type[]
                            {
                                typeof (TimePeriod)
                            });
                    }
                }
                catch (ExprValidationException ex)
                {
                    throw new ObserverParameterException(ex.Message, ex);
                }
                ExprNode dateNode = dateNamedNode == null ? null : dateNamedNode.ChildNodes[0];
                ExprNode repetitionsNode = repetitionsNamedNode == null ? null : repetitionsNamedNode.ChildNodes[0];
                ExprTimePeriod periodNode = periodNamedNode == null
                    ? null
                    : (ExprTimePeriod) periodNamedNode.ChildNodes[0];
                ScheduleComputer = new TimerScheduleSpecComputeFromExpr(dateNode, repetitionsNode, periodNode);
            }

            if (allConstantResult)
            {
                try
                {
                    Spec = ScheduleComputer.Compute(
                        convertor, new MatchedEventMapImpl(convertor.MatchedEventMapMeta), null, validationContext.MethodResolutionService.EngineImportService.TimeZone);
                }
                catch (ScheduleParameterException ex)
                {
                    throw new ObserverParameterException(ex.Message, ex);
                }
            }
        }
Пример #19
0
        public override AggregationMethodFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            var positionalParams = base.PositionalParams;

            if (positionalParams.Length == 0)
            {
                throw new ExprValidationException(
                          "The rate aggregation function minimally requires a numeric constant or expression as a parameter.");
            }

            ExprNode first = positionalParams[0];

            if (first.IsConstantResult)
            {
                const string message =
                    "The rate aggregation function requires a numeric constant or time period as the first parameter in the constant-value notation";
                long intervalTime;
                if (first is ExprTimePeriod)
                {
                    double secInterval = ((ExprTimePeriod)first).EvaluateAsSeconds(
                        null, true, validationContext.ExprEvaluatorContext);
                    intervalTime = validationContext.EngineImportService.TimeAbacus.DeltaForSecondsDouble(secInterval);
                }
                else if (ExprNodeUtility.IsConstantValueExpr(first))
                {
                    if (!first.ExprEvaluator.ReturnType.IsNumeric())
                    {
                        throw new ExprValidationException(message);
                    }
                    var num =
                        first.ExprEvaluator.Evaluate(
                            new EvaluateParams(null, true, validationContext.ExprEvaluatorContext));
                    intervalTime = validationContext.EngineImportService.TimeAbacus.DeltaForSecondsNumber(num);
                }
                else
                {
                    throw new ExprValidationException(message);
                }

                return
                    (validationContext.EngineImportService.AggregationFactoryFactory.MakeRate(
                         validationContext.StatementExtensionSvcContext, this, true, intervalTime,
                         validationContext.TimeProvider, validationContext.EngineImportService.TimeAbacus));
            }

            const string messageX =
                "The rate aggregation function requires a property or expression returning a non-constant long-type value as the first parameter in the timestamp-property notation";
            Type boxedParamOne = first.ExprEvaluator.ReturnType.GetBoxedType();

            if (boxedParamOne != typeof(long?))
            {
                throw new ExprValidationException(messageX);
            }
            if (first.IsConstantResult)
            {
                throw new ExprValidationException(messageX);
            }
            if (first is ExprTimestampNode)
            {
                throw new ExprValidationException(
                          "The rate aggregation function does not allow the current engine timestamp as a parameter");
            }
            if (positionalParams.Length > 1)
            {
                if (!TypeHelper.IsNumeric(positionalParams[1].ExprEvaluator.ReturnType))
                {
                    throw new ExprValidationException(
                              "The rate aggregation function accepts an expression returning a numeric value to accumulate as an optional second parameter");
                }
            }
            bool hasDataWindows = ExprNodeUtility.HasRemoveStreamForAggregations(
                first, validationContext.StreamTypeService, validationContext.IsResettingAggregations);

            if (!hasDataWindows)
            {
                throw new ExprValidationException(
                          "The rate aggregation function in the timestamp-property notation requires data windows");
            }
            return
                (validationContext.EngineImportService.AggregationFactoryFactory.MakeRate(
                     validationContext.StatementExtensionSvcContext, this, false, -1, validationContext.TimeProvider,
                     validationContext.EngineImportService.TimeAbacus));
        }
Пример #20
0
        public void Init(
            int?streamOfProviderIfApplicable,
            EnumMethodEnum enumMethodEnum,
            String enumMethodUsedName,
            EPType typeInfo,
            IList <ExprNode> parameters,
            ExprValidationContext validationContext)
        {
            var eventTypeColl           = EPTypeHelper.GetEventTypeMultiValued(typeInfo);
            var eventTypeBean           = EPTypeHelper.GetEventTypeSingleValued(typeInfo);
            var collectionComponentType = EPTypeHelper.GetClassMultiValued(typeInfo);

            _enumMethodEnum      = enumMethodEnum;
            _enumMethodUsedName  = enumMethodUsedName;
            _streamCountIncoming = validationContext.StreamTypeService.EventTypes.Length;

            if (eventTypeColl == null && collectionComponentType == null && eventTypeBean == null)
            {
                throw new ExprValidationException(
                          "Invalid input for built-in enumeration method '" + enumMethodUsedName +
                          "', expecting collection of event-type or scalar values as input, received " +
                          EPTypeHelper.ToTypeDescriptive(typeInfo));
            }

            // compile parameter abstract for validation against available footprints
            var footprintProvided = DotMethodUtil.GetProvidedFootprint(parameters);

            // validate parameters
            DotMethodInputTypeMatcher inputTypeMatcher = new ProxyDotMethodInputTypeMatcher
            {
                ProcMatches = fp =>
                {
                    if (fp.Input == DotMethodFPInputEnum.EVENTCOLL && eventTypeBean == null && eventTypeColl == null)
                    {
                        return(false);
                    }
                    if (fp.Input == DotMethodFPInputEnum.SCALAR_ANY && collectionComponentType == null)
                    {
                        return(false);
                    }
                    return(true);
                }
            };

            var footprint = DotMethodUtil.ValidateParametersDetermineFootprint(
                enumMethodEnum.GetFootprints(), DotMethodTypeEnum.ENUM, enumMethodUsedName, footprintProvided,
                inputTypeMatcher);

            // validate input criteria met for this footprint
            if (footprint.Input != DotMethodFPInputEnum.ANY)
            {
                var message = "Invalid input for built-in enumeration method '" + enumMethodUsedName + "' and " +
                              footprint.Parameters.Length + "-parameter footprint, expecting collection of ";
                var received = " as input, received " + EPTypeHelper.ToTypeDescriptive(typeInfo);
                if (footprint.Input == DotMethodFPInputEnum.EVENTCOLL && eventTypeColl == null)
                {
                    throw new ExprValidationException(message + "events" + received);
                }
                if (footprint.Input.IsScalar() && collectionComponentType == null)
                {
                    throw new ExprValidationException(message + "values (typically scalar values)" + received);
                }
                if (footprint.Input == DotMethodFPInputEnum.SCALAR_NUMERIC && !collectionComponentType.IsNumeric())
                {
                    throw new ExprValidationException(message + "numeric values" + received);
                }
            }

            // manage context of this lambda-expression in regards to outer lambda-expression that may call this one.
            ExpressionResultCacheForEnumerationMethod enumerationMethodCache = validationContext.ExprEvaluatorContext.ExpressionResultCacheService.AllocateEnumerationMethod;

            enumerationMethodCache.PushStack(this);

            var bodiesAndParameters = new List <ExprDotEvalParam>();
            var count          = 0;
            var inputEventType = eventTypeBean ?? eventTypeColl;

            foreach (var node in parameters)
            {
                var bodyAndParameter = GetBodyAndParameter(
                    enumMethodUsedName, count++, node, inputEventType, collectionComponentType, validationContext,
                    bodiesAndParameters, footprint);
                bodiesAndParameters.Add(bodyAndParameter);
            }

            _enumEval = GetEnumEval(
                validationContext.EngineImportService, validationContext.EventAdapterService,
                validationContext.StreamTypeService, validationContext.StatementId, enumMethodUsedName,
                bodiesAndParameters, inputEventType, collectionComponentType, _streamCountIncoming,
                validationContext.IsDisablePropertyExpressionEventCollCache);
            _enumEvalNumRequiredEvents = _enumEval.StreamNumSize;

            // determine the stream ids of event properties asked for in the Evaluator(s)
            var streamsRequired = new HashSet <int>();
            var visitor         = new ExprNodeIdentifierCollectVisitor();

            foreach (var desc in bodiesAndParameters)
            {
                desc.Body.Accept(visitor);
                foreach (var ident in visitor.ExprProperties)
                {
                    streamsRequired.Add(ident.StreamId);
                }
            }
            if (streamOfProviderIfApplicable != null)
            {
                streamsRequired.Add(streamOfProviderIfApplicable.Value);
            }

            // We turn on caching if the stack is not empty (we are an inner lambda) and the dependency does not include the stream.
            var isInner = !enumerationMethodCache.PopLambda();

            if (isInner)
            {
                // If none of the properties that the current lambda uses comes from the ultimate Parent(s) or subsequent streams, then cache.
                var parents = enumerationMethodCache.GetStack();
                var found   = false;
                foreach (var req in streamsRequired)
                {
                    var first          = (ExprDotEvalEnumMethodBase)parents.First;
                    var parentIncoming = first._streamCountIncoming - 1;
                    var selfAdded      = _streamCountIncoming; // the one we use ourselfs
                    if (req > parentIncoming && req < selfAdded)
                    {
                        found = true;
                    }
                }
                _cache = !found;
            }
        }
Пример #21
0
        private static void RecursiveCompile(
            EvalFactoryNode evalNode,
            StatementContext context,
            ExprEvaluatorContext evaluatorContext,
            ICollection <string> eventTypeReferences,
            bool isInsertInto,
            MatchEventSpec tags,
            Deque <int> subexpressionIdStack,
            Stack <EvalFactoryNode> parentNodeStack,
            ICollection <string> allTagNamesOrdered)
        {
            var counter = 0;

            parentNodeStack.Push(evalNode);
            foreach (var child in evalNode.ChildNodes)
            {
                subexpressionIdStack.AddLast(counter++);
                RecursiveCompile(
                    child, context, evaluatorContext, eventTypeReferences, isInsertInto, tags, subexpressionIdStack,
                    parentNodeStack, allTagNamesOrdered);
                subexpressionIdStack.RemoveLast();
            }
            parentNodeStack.Pop();

            LinkedHashMap <string, Pair <EventType, string> > newTaggedEventTypes = null;
            LinkedHashMap <string, Pair <EventType, string> > newArrayEventTypes  = null;

            if (evalNode is EvalFilterFactoryNode)
            {
                var filterNode = (EvalFilterFactoryNode)evalNode;
                var eventName  = filterNode.RawFilterSpec.EventTypeName;
                if (context.TableService.GetTableMetadata(eventName) != null)
                {
                    throw new ExprValidationException("Tables cannot be used in pattern filter atoms");
                }

                var resolvedEventType = FilterStreamSpecRaw.ResolveType(
                    context.EngineURI, eventName, context.EventAdapterService, context.PlugInTypeResolutionURIs);
                var finalEventType       = resolvedEventType;
                var optionalTag          = filterNode.EventAsName;
                var isPropertyEvaluation = false;
                var isParentMatchUntil   = IsParentMatchUntil(evalNode, parentNodeStack);

                // obtain property event type, if final event type is properties
                if (filterNode.RawFilterSpec.OptionalPropertyEvalSpec != null)
                {
                    var optionalPropertyEvaluator =
                        PropertyEvaluatorFactory.MakeEvaluator(
                            context.Container,
                            filterNode.RawFilterSpec.OptionalPropertyEvalSpec,
                            resolvedEventType,
                            filterNode.EventAsName,
                            context.EventAdapterService,
                            context.EngineImportService,
                            context.SchedulingService,
                            context.VariableService,
                            context.ScriptingService,
                            context.TableService,
                            context.EngineURI,
                            context.StatementId,
                            context.StatementName,
                            context.Annotations,
                            subexpressionIdStack,
                            context.ConfigSnapshot,
                            context.NamedWindowMgmtService,
                            context.StatementExtensionServicesContext);
                    finalEventType       = optionalPropertyEvaluator.FragmentEventType;
                    isPropertyEvaluation = true;
                }

                if (finalEventType is EventTypeSPI)
                {
                    eventTypeReferences.Add(((EventTypeSPI)finalEventType).Metadata.PrimaryName);
                }

                // If a tag was supplied for the type, the tags must stay with this type, i.e. a=BeanA -> b=BeanA -> a=BeanB is a no
                if (optionalTag != null)
                {
                    var       pair         = tags.TaggedEventTypes.Get(optionalTag);
                    EventType existingType = null;
                    if (pair != null)
                    {
                        existingType = pair.First;
                    }
                    if (existingType == null)
                    {
                        pair = tags.ArrayEventTypes.Get(optionalTag);
                        if (pair != null)
                        {
                            throw new ExprValidationException(
                                      "Tag '" + optionalTag + "' for event '" + eventName +
                                      "' used in the repeat-until operator cannot also appear in other filter expressions");
                        }
                    }
                    if ((existingType != null) && (existingType != finalEventType))
                    {
                        throw new ExprValidationException(
                                  "Tag '" + optionalTag + "' for event '" + eventName +
                                  "' has already been declared for events of type " + existingType.UnderlyingType.FullName);
                    }
                    pair = new Pair <EventType, string>(finalEventType, eventName);

                    // add tagged type
                    if (isPropertyEvaluation || isParentMatchUntil)
                    {
                        newArrayEventTypes = new LinkedHashMap <string, Pair <EventType, string> >();
                        newArrayEventTypes.Put(optionalTag, pair);
                    }
                    else
                    {
                        newTaggedEventTypes = new LinkedHashMap <string, Pair <EventType, string> >();
                        newTaggedEventTypes.Put(optionalTag, pair);
                    }
                }

                // For this filter, filter types are all known tags at this time,
                // and additionally stream 0 (self) is our event type.
                // Stream type service allows resolution by property name event if that name appears in other tags.
                // by defaulting to stream zero.
                // Stream zero is always the current event type, all others follow the order of the map (stream 1 to N).
                var selfStreamName = optionalTag;
                if (selfStreamName == null)
                {
                    selfStreamName = "s_" + UuidGenerator.Generate();
                }
                var filterTypes = new LinkedHashMap <string, Pair <EventType, string> >();
                var typePair    = new Pair <EventType, string>(finalEventType, eventName);
                filterTypes.Put(selfStreamName, typePair);
                filterTypes.PutAll(tags.TaggedEventTypes);

                // for the filter, specify all tags used
                var filterTaggedEventTypes = new LinkedHashMap <string, Pair <EventType, string> >(tags.TaggedEventTypes);
                filterTaggedEventTypes.Remove(optionalTag);

                // handle array tags (match-until clause)
                LinkedHashMap <string, Pair <EventType, string> > arrayCompositeEventTypes = null;
                if (tags.ArrayEventTypes != null && !tags.ArrayEventTypes.IsEmpty())
                {
                    arrayCompositeEventTypes = new LinkedHashMap <string, Pair <EventType, string> >();
                    var patternSubexEventType = GetPatternSubexEventType(
                        context.StatementId, "pattern", subexpressionIdStack);

                    foreach (var entry in tags.ArrayEventTypes)
                    {
                        var specificArrayType = new LinkedHashMap <string, Pair <EventType, string> >();
                        specificArrayType.Put(entry.Key, entry.Value);
                        var arrayTagCompositeEventType =
                            context.EventAdapterService.CreateSemiAnonymousMapType(
                                patternSubexEventType, Collections.GetEmptyMap <string, Pair <EventType, string> >(),
                                specificArrayType, isInsertInto);
                        context.StatementSemiAnonymousTypeRegistry.Register(arrayTagCompositeEventType);

                        var tag = entry.Key;
                        if (!filterTypes.ContainsKey(tag))
                        {
                            var pair = new Pair <EventType, string>(arrayTagCompositeEventType, tag);
                            filterTypes.Put(tag, pair);
                            arrayCompositeEventTypes.Put(tag, pair);
                        }
                    }
                }

                StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                    filterTypes, context.EngineURI, true, false);
                var exprNodes = filterNode.RawFilterSpec.FilterExpressions;

                var spec = FilterSpecCompiler.MakeFilterSpec(
                    resolvedEventType, eventName, exprNodes,
                    filterNode.RawFilterSpec.OptionalPropertyEvalSpec,
                    filterTaggedEventTypes,
                    arrayCompositeEventTypes,
                    streamTypeService,
                    null, context, subexpressionIdStack);
                filterNode.FilterSpec = spec;
            }
            else if (evalNode is EvalObserverFactoryNode)
            {
                var observerNode = (EvalObserverFactoryNode)evalNode;
                try
                {
                    var observerFactory = context.PatternResolutionService.Create(observerNode.PatternObserverSpec);

                    var streamTypeService = GetStreamTypeService(
                        context.EngineURI, context.StatementId, context.EventAdapterService, tags.TaggedEventTypes,
                        tags.ArrayEventTypes, subexpressionIdStack, "observer", context);
                    var validationContext = new ExprValidationContext(
                        context.Container,
                        streamTypeService,
                        context.EngineImportService,
                        context.StatementExtensionServicesContext, null,
                        context.SchedulingService,
                        context.VariableService,
                        context.TableService, evaluatorContext,
                        context.EventAdapterService,
                        context.StatementName,
                        context.StatementId,
                        context.Annotations,
                        context.ContextDescriptor,
                        context.ScriptingService,
                        false, false, false, false, null, false);
                    var validated = ValidateExpressions(
                        ExprNodeOrigin.PATTERNOBSERVER, observerNode.PatternObserverSpec.ObjectParameters,
                        validationContext);

                    MatchedEventConvertor convertor = new MatchedEventConvertorImpl(
                        tags.TaggedEventTypes, tags.ArrayEventTypes, allTagNamesOrdered, context.EventAdapterService);

                    observerNode.ObserverFactory = observerFactory;
                    observerFactory.SetObserverParameters(validated, convertor, validationContext);
                }
                catch (ObserverParameterException e)
                {
                    throw new ExprValidationException(
                              "Invalid parameter for pattern observer '" + observerNode.ToPrecedenceFreeEPL() + "': " +
                              e.Message, e);
                }
                catch (PatternObjectException e)
                {
                    throw new ExprValidationException(
                              "Failed to resolve pattern observer '" + observerNode.ToPrecedenceFreeEPL() + "': " + e.Message,
                              e);
                }
            }
            else if (evalNode is EvalGuardFactoryNode)
            {
                var guardNode = (EvalGuardFactoryNode)evalNode;
                try
                {
                    var guardFactory = context.PatternResolutionService.Create(guardNode.PatternGuardSpec);

                    var streamTypeService = GetStreamTypeService(
                        context.EngineURI, context.StatementId, context.EventAdapterService, tags.TaggedEventTypes,
                        tags.ArrayEventTypes, subexpressionIdStack, "guard", context);
                    var validationContext = new ExprValidationContext(
                        context.Container,
                        streamTypeService,
                        context.EngineImportService,
                        context.StatementExtensionServicesContext, null,
                        context.SchedulingService,
                        context.VariableService,
                        context.TableService, evaluatorContext,
                        context.EventAdapterService,
                        context.StatementName,
                        context.StatementId,
                        context.Annotations,
                        context.ContextDescriptor,
                        context.ScriptingService,
                        false, false, false, false, null, false);
                    var validated = ValidateExpressions(
                        ExprNodeOrigin.PATTERNGUARD, guardNode.PatternGuardSpec.ObjectParameters, validationContext);

                    MatchedEventConvertor convertor = new MatchedEventConvertorImpl(
                        tags.TaggedEventTypes, tags.ArrayEventTypes, allTagNamesOrdered, context.EventAdapterService);

                    guardNode.GuardFactory = guardFactory;
                    guardFactory.SetGuardParameters(validated, convertor);
                }
                catch (GuardParameterException e)
                {
                    throw new ExprValidationException(
                              "Invalid parameter for pattern guard '" + guardNode.ToPrecedenceFreeEPL() + "': " + e.Message, e);
                }
                catch (PatternObjectException e)
                {
                    throw new ExprValidationException(
                              "Failed to resolve pattern guard '" + guardNode.ToPrecedenceFreeEPL() + "': " + e.Message, e);
                }
            }
            else if (evalNode is EvalEveryDistinctFactoryNode)
            {
                var distinctNode             = (EvalEveryDistinctFactoryNode)evalNode;
                var matchEventFromChildNodes = AnalyzeMatchEvent(distinctNode);
                var streamTypeService        = GetStreamTypeService(
                    context.EngineURI, context.StatementId, context.EventAdapterService,
                    matchEventFromChildNodes.TaggedEventTypes, matchEventFromChildNodes.ArrayEventTypes,
                    subexpressionIdStack, "every-distinct", context);
                var validationContext = new ExprValidationContext(
                    context.Container,
                    streamTypeService,
                    context.EngineImportService,
                    context.StatementExtensionServicesContext, null,
                    context.SchedulingService,
                    context.VariableService,
                    context.TableService, evaluatorContext,
                    context.EventAdapterService,
                    context.StatementName,
                    context.StatementId,
                    context.Annotations,
                    context.ContextDescriptor,
                    context.ScriptingService,
                    false, false, false, false, null, false);
                IList <ExprNode> validated;
                try
                {
                    validated = ValidateExpressions(
                        ExprNodeOrigin.PATTERNEVERYDISTINCT, distinctNode.Expressions, validationContext);
                }
                catch (ExprValidationPropertyException ex)
                {
                    throw new ExprValidationPropertyException(
                              ex.Message +
                              ", every-distinct requires that all properties resolve from sub-expressions to the every-distinct",
                              ex.InnerException);
                }

                MatchedEventConvertor convertor =
                    new MatchedEventConvertorImpl(
                        matchEventFromChildNodes.TaggedEventTypes, matchEventFromChildNodes.ArrayEventTypes,
                        allTagNamesOrdered, context.EventAdapterService);

                distinctNode.Convertor = convertor;

                // Determine whether some expressions are constants or time period
                IList <ExprNode>             distinctExpressions  = new List <ExprNode>();
                ExprTimePeriodEvalDeltaConst timeDeltaComputation = null;
                ExprNode expiryTimeExp = null;
                var      count         = -1;
                var      last          = validated.Count - 1;
                foreach (var expr in validated)
                {
                    count++;
                    if (count == last && expr is ExprTimePeriod)
                    {
                        expiryTimeExp = expr;
                        var timePeriodExpr = (ExprTimePeriod)expiryTimeExp;
                        timeDeltaComputation =
                            timePeriodExpr.ConstEvaluator(new ExprEvaluatorContextStatement(context, false));
                    }
                    else if (expr.IsConstantResult)
                    {
                        if (count == last)
                        {
                            var evaluateParams = new EvaluateParams(null, true, evaluatorContext);
                            var value          = expr.ExprEvaluator.Evaluate(evaluateParams);
                            if (!(value.IsNumber()))
                            {
                                throw new ExprValidationException(
                                          "Invalid parameter for every-distinct, expected number of seconds constant (constant not considered for distinct)");
                            }

                            var secondsExpire = expr.ExprEvaluator.Evaluate(evaluateParams);

                            long?timeExpire;
                            if (secondsExpire == null)
                            {
                                timeExpire = null;
                            }
                            else
                            {
                                timeExpire = context.TimeAbacus.DeltaForSecondsNumber(secondsExpire);
                            }

                            if (timeExpire != null && timeExpire > 0)
                            {
                                timeDeltaComputation = new ExprTimePeriodEvalDeltaConstGivenDelta(timeExpire.Value);
                                expiryTimeExp        = expr;
                            }
                            else
                            {
                                Log.Warn("Invalid seconds-expire " + timeExpire + " for " + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(expr));
                            }
                        }
                        else
                        {
                            Log.Warn(
                                "Every-distinct node utilizes an expression returning a constant value, please check expression '{0}', not adding expression to distinct-value expression list",
                                expr.ToExpressionStringMinPrecedenceSafe());
                        }
                    }
                    else
                    {
                        distinctExpressions.Add(expr);
                    }
                }
                if (distinctExpressions.IsEmpty())
                {
                    throw new ExprValidationException(
                              "Every-distinct node requires one or more distinct-value expressions that each return non-constant result values");
                }
                distinctNode.SetDistinctExpressions(distinctExpressions, timeDeltaComputation, expiryTimeExp);
            }
            else if (evalNode is EvalMatchUntilFactoryNode)
            {
                var matchUntilNode = (EvalMatchUntilFactoryNode)evalNode;

                // compile bounds expressions, if any
                var untilMatchEventSpec = new MatchEventSpec(tags.TaggedEventTypes, tags.ArrayEventTypes);
                var streamTypeService   = GetStreamTypeService(
                    context.EngineURI, context.StatementId, context.EventAdapterService,
                    untilMatchEventSpec.TaggedEventTypes, untilMatchEventSpec.ArrayEventTypes, subexpressionIdStack,
                    "until", context);
                var validationContext = new ExprValidationContext(
                    context.Container,
                    streamTypeService,
                    context.EngineImportService,
                    context.StatementExtensionServicesContext, null,
                    context.SchedulingService,
                    context.VariableService,
                    context.TableService, evaluatorContext,
                    context.EventAdapterService,
                    context.StatementName,
                    context.StatementId,
                    context.Annotations,
                    context.ContextDescriptor,
                    context.ScriptingService,
                    false, false, false, false, null, false);

                var lower = ValidateBounds(matchUntilNode.LowerBounds, validationContext);
                matchUntilNode.LowerBounds = lower;

                var upper = ValidateBounds(matchUntilNode.UpperBounds, validationContext);
                matchUntilNode.UpperBounds = upper;

                var single = ValidateBounds(matchUntilNode.SingleBound, validationContext);
                matchUntilNode.SingleBound = single;

                var convertor = new MatchedEventConvertorImpl(
                    untilMatchEventSpec.TaggedEventTypes, untilMatchEventSpec.ArrayEventTypes, allTagNamesOrdered,
                    context.EventAdapterService);
                matchUntilNode.Convertor = convertor;

                // compile new tag lists
                ISet <string> arrayTags = null;
                var           matchUntilAnalysisResult = EvalNodeUtil.RecursiveAnalyzeChildNodes(matchUntilNode.ChildNodes[0]);
                foreach (var filterNode in matchUntilAnalysisResult.FilterNodes)
                {
                    var optionalTag = filterNode.EventAsName;
                    if (optionalTag != null)
                    {
                        if (arrayTags == null)
                        {
                            arrayTags = new HashSet <string>();
                        }
                        arrayTags.Add(optionalTag);
                    }
                }

                if (arrayTags != null)
                {
                    foreach (var arrayTag in arrayTags)
                    {
                        if (!tags.ArrayEventTypes.ContainsKey(arrayTag))
                        {
                            tags.ArrayEventTypes.Put(arrayTag, tags.TaggedEventTypes.Get(arrayTag));
                            tags.TaggedEventTypes.Remove(arrayTag);
                        }
                    }
                }
                matchUntilNode.TagsArrayed = GetIndexesForTags(allTagNamesOrdered, arrayTags);
            }
            else if (evalNode is EvalFollowedByFactoryNode)
            {
                var followedByNode = (EvalFollowedByFactoryNode)evalNode;
                StreamTypeService streamTypeService = new StreamTypeServiceImpl(context.EngineURI, false);
                var validationContext = new ExprValidationContext(
                    context.Container,
                    streamTypeService,
                    context.EngineImportService,
                    context.StatementExtensionServicesContext, null,
                    context.SchedulingService,
                    context.VariableService,
                    context.TableService,
                    evaluatorContext,
                    context.EventAdapterService,
                    context.StatementName,
                    context.StatementId,
                    context.Annotations,
                    context.ContextDescriptor,
                    context.ScriptingService,
                    false, false, false, false, null, false);

                if (followedByNode.OptionalMaxExpressions != null)
                {
                    IList <ExprNode> validated = new List <ExprNode>();
                    foreach (var maxExpr in followedByNode.OptionalMaxExpressions)
                    {
                        if (maxExpr == null)
                        {
                            validated.Add(null);
                        }
                        else
                        {
                            var visitor = new ExprNodeSummaryVisitor();
                            maxExpr.Accept(visitor);
                            if (!visitor.IsPlain)
                            {
                                var errorMessage = "Invalid maximum expression in followed-by, " + visitor.GetMessage() +
                                                   " are not allowed within the expression";
                                Log.Error(errorMessage);
                                throw new ExprValidationException(errorMessage);
                            }

                            var validatedExpr = ExprNodeUtility.GetValidatedSubtree(
                                ExprNodeOrigin.FOLLOWEDBYMAX, maxExpr, validationContext);
                            validated.Add(validatedExpr);
                            if ((validatedExpr.ExprEvaluator.ReturnType == null) ||
                                (!validatedExpr.ExprEvaluator.ReturnType.IsNumeric()))
                            {
                                var message = "Invalid maximum expression in followed-by, the expression must return an integer value";
                                throw new ExprValidationException(message);
                            }
                        }
                    }
                    followedByNode.OptionalMaxExpressions = validated;
                }
            }

            if (newTaggedEventTypes != null)
            {
                tags.TaggedEventTypes.PutAll(newTaggedEventTypes);
            }
            if (newArrayEventTypes != null)
            {
                tags.ArrayEventTypes.PutAll(newArrayEventTypes);
            }
        }
Пример #22
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (ChildNodes.Length != 2) {
                throw new ExprValidationException("Arithmatic node must have 2 parameters");
            }

            foreach (var child in ChildNodes) {
                var childType = child.Forge.EvaluationType;
                if (!childType.IsNumeric()) {
                    throw new ExprValidationException(
                        "Implicit conversion from datatype '" +
                        childType.CleanName() +
                        "' to numeric is not allowed");
                }
            }

            // Determine result type, set up compute function
            var lhs = ChildNodes[0];
            var rhs = ChildNodes[1];
            var lhsType = lhs.Forge.EvaluationType;
            var rhsType = rhs.Forge.EvaluationType;

            Type resultType;

            // If both sides are unboxed, then the result is also unboxed
            if (!lhsType.IsNullable() && !rhsType.IsNullable()) {
                if ((lhsType == typeof(short)) && (rhsType == typeof(short))) {
                    resultType = typeof(int);
                } else if (lhsType == typeof(byte) && (rhsType == typeof(byte))) {
                    resultType = typeof(int);
                } else if (lhsType == rhsType) {
                    resultType = rhsType;
                }
                else {
                    resultType = lhsType
                        .GetArithmaticCoercionType(rhsType)
                        .GetUnboxedType();
                }
            }
            else if ((lhsType == typeof(short) || lhsType == typeof(short?)) &&
                     (rhsType == typeof(short) || rhsType == typeof(short?))) {
                resultType = typeof(int?);
            }
            else if ((lhsType == typeof(byte) || lhsType == typeof(byte?)) &&
                     (rhsType == typeof(byte) || rhsType == typeof(byte?))) {
                resultType = typeof(int?);
            }
            else if (lhsType == rhsType) {
                resultType = rhsType.GetBoxedType();
            }
            else {
                resultType = lhsType.GetArithmaticCoercionType(rhsType);
            }

            if (MathArithTypeEnum == MathArithTypeEnum.DIVIDE && !_isIntegerDivision) {
                if (!resultType.IsDecimal()) {
                    resultType = typeof(double?);
                }
            }

            // If ths isDivisionByZeroReturnsNull is set, it requires promotion to boxed types
            // to support passing back null.
            if (_isDivisionByZeroReturnsNull) {
                resultType = resultType.GetBoxedType();
            }
            
            var arithTypeEnumComputer = MathArithType.GetComputer(
                MathArithTypeEnum,
                resultType,
                lhsType,
                rhsType,
                _isIntegerDivision,
                _isDivisionByZeroReturnsNull,
                validationContext.ImportService.DefaultMathContext);
            _forge = new ExprMathNodeForge(this, arithTypeEnumComputer, resultType);
            return null;
        }
Пример #23
0
        private ExprDotEvalParam GetBodyAndParameter(
            String enumMethodUsedName,
            int parameterNum,
            ExprNode parameterNode,
            EventType inputEventType,
            Type collectionComponentType,
            ExprValidationContext validationContext,
            IList <ExprDotEvalParam> priorParameters,
            DotMethodFP footprint)
        {
            // handle an expression that is a constant or other (not =>)
            if (!(parameterNode is ExprLambdaGoesNode))
            {
                // no node subtree validation is required here, the chain parameter validation has taken place in ExprDotNode.validate
                // validation of parameter types has taken place in footprint matching
                return(new ExprDotEvalParamExpr(parameterNum, parameterNode, parameterNode.ExprEvaluator));
            }

            var goesNode = (ExprLambdaGoesNode)parameterNode;

            // Get secondary
            var additionalTypes = GetAddStreamTypes(
                enumMethodUsedName, goesNode.GoesToNames, inputEventType, collectionComponentType, priorParameters, validationContext.EventAdapterService);
            var additionalStreamNames = goesNode.GoesToNames.ToArray();

            ValidateDuplicateStreamNames(validationContext.StreamTypeService.StreamNames, additionalStreamNames);

            // add name and type to list of known types
            var addTypes =
                (EventType[])
                CollectionUtil.ArrayExpandAddElements(
                    validationContext.StreamTypeService.EventTypes, additionalTypes);
            var addNames =
                (String[])
                CollectionUtil.ArrayExpandAddElements(
                    validationContext.StreamTypeService.StreamNames, additionalStreamNames);

            var types = new StreamTypeServiceImpl(
                addTypes, addNames, new bool[addTypes.Length], null, false);

            // validate expression body
            var filter = goesNode.ChildNodes[0];

            try
            {
                var filterValidationContext = new ExprValidationContext(types, validationContext);
                filter = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.DECLAREDEXPRBODY, filter, filterValidationContext);
            }
            catch (ExprValidationException ex)
            {
                throw new ExprValidationException(
                          "Error validating enumeration method '" + enumMethodUsedName + "' parameter " + parameterNum + ": " +
                          ex.Message, ex);
            }

            var filterEvaluator = filter.ExprEvaluator;
            var expectedType    = footprint.Parameters[parameterNum].ParamType;

            // Lambda-methods don't use a specific expected return-type, so passing null for type is fine.
            DotMethodUtil.ValidateSpecificType(
                enumMethodUsedName, DotMethodTypeEnum.ENUM, expectedType, null, filterEvaluator.ReturnType, parameterNum,
                filter);

            var numStreamsIncoming = validationContext.StreamTypeService.EventTypes.Length;

            return(new ExprDotEvalParamLambda(
                       parameterNum, filter, filterEvaluator,
                       numStreamsIncoming, goesNode.GoesToNames, additionalTypes));
        }
        private ExprAggMultiFunctionSortedMinMaxByNodeFactory HandleNonTable(ExprValidationContext validationContext)

        {
            if (PositionalParams.Length == 0)
            {
                throw new ExprValidationException("Missing the sort criteria expression");
            }

            // validate that the streams referenced in the criteria are a single stream's
            var streams = ExprNodeUtility.GetIdentStreamNumbers(PositionalParams[0]);

            if (streams.Count > 1 || streams.IsEmpty())
            {
                throw new ExprValidationException(ErrorPrefix + " requires that any parameter expressions evaluate properties of the same stream");
            }
            int streamNum = streams.First();

            // validate that there is a remove stream, use "ever" if not
            var forceEver = false;

            if (!_ever && ExprAggMultiFunctionLinearAccessNode.GetIstreamOnly(validationContext.StreamTypeService, streamNum))
            {
                if (_sortedwin)
                {
                    throw new ExprValidationException(ErrorPrefix + " requires that a data window is declared for the stream");
                }
                forceEver = true;
            }

            // determine typing and evaluation
            _containedType = validationContext.StreamTypeService.EventTypes[streamNum];

            var componentType      = _containedType.UnderlyingType;
            var accessorResultType = componentType;
            AggregationAccessor accessor;
            TableMetadata       tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(_containedType);

            if (!_sortedwin)
            {
                if (tableMetadata != null)
                {
                    accessor = new AggregationAccessorMinMaxByTable(_max, tableMetadata);
                }
                else
                {
                    accessor = new AggregationAccessorMinMaxByNonTable(_max);
                }
            }
            else
            {
                if (tableMetadata != null)
                {
                    accessor = new AggregationAccessorSortedTable(_max, componentType, tableMetadata);
                }
                else
                {
                    accessor = new AggregationAccessorSortedNonTable(_max, componentType);
                }
                accessorResultType = TypeHelper.GetArrayType(accessorResultType);
            }

            Pair <ExprNode[], bool[]> criteriaExpressions = CriteriaExpressions;

            AggregationStateTypeWStream type;

            if (_ever)
            {
                type = _max ? AggregationStateTypeWStream.MAXEVER : AggregationStateTypeWStream.MINEVER;
            }
            else
            {
                type = AggregationStateTypeWStream.SORTED;
            }
            var stateKey = new AggregationStateKeyWStream(streamNum, _containedType, type, criteriaExpressions.First);

            var stateFactoryFactory = new
                                      SortedAggregationStateFactoryFactory(validationContext.MethodResolutionService,
                                                                           ExprNodeUtility.GetEvaluators(criteriaExpressions.First),
                                                                           criteriaExpressions.Second, _ever, streamNum, this);

            return(new ExprAggMultiFunctionSortedMinMaxByNodeFactory(this, accessor, accessorResultType, _containedType, stateKey, stateFactoryFactory, AggregationAgentDefault.INSTANCE));
        }
        public override EPStatementStartResult StartInternal(
            EPServicesContext services,
            StatementContext statementContext,
            bool isNewStatement,
            bool isRecoveringStatement,
            bool isRecoveringResilient)
        {
            var createDesc = _statementSpec.CreateVariableDesc;

            VariableServiceUtil.CheckAlreadyDeclaredTable(createDesc.VariableName, services.TableService);

            // Get assignment value
            object value = null;

            if (createDesc.Assignment != null)
            {
                // Evaluate assignment expression
                StreamTypeService typeService = new StreamTypeServiceImpl(
                    new EventType[0], new string[0], new bool[0], services.EngineURI, false);
                var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
                var validationContext    = new ExprValidationContext(
                    typeService,
                    statementContext.MethodResolutionService, null,
                    statementContext.SchedulingService,
                    statementContext.VariableService,
                    statementContext.TableService, evaluatorContextStmt,
                    statementContext.EventAdapterService,
                    statementContext.StatementName, statementContext.StatementId,
                    statementContext.Annotations,
                    statementContext.ContextDescriptor,
                    statementContext.ScriptingService,
                    false, false, false, false, null, false);
                var validated = ExprNodeUtility.GetValidatedSubtree(
                    ExprNodeOrigin.VARIABLEASSIGN, createDesc.Assignment, validationContext);
                value = validated.ExprEvaluator.Evaluate(new EvaluateParams(null, true, evaluatorContextStmt));
            }

            // Create variable
            try
            {
                services.VariableService.CreateNewVariable(
                    _statementSpec.OptionalContextName, createDesc.VariableName, createDesc.VariableType, createDesc.IsConstant,
                    createDesc.IsArray, createDesc.IsArrayOfPrimitive, value, services.EngineImportService);
            }
            catch (VariableExistsException ex)
            {
                // for new statement we don't allow creating the same variable
                if (isNewStatement)
                {
                    throw new ExprValidationException("Cannot create variable: " + ex.Message, ex);
                }
            }
            catch (VariableDeclarationException ex)
            {
                throw new ExprValidationException("Cannot create variable: " + ex.Message, ex);
            }

            var destroyMethod = new EPStatementDestroyCallbackList();

            destroyMethod.AddCallback(new ProxyDestroyCallback(() =>
            {
                try
                {
                    services.StatementVariableRefService.RemoveReferencesStatement(statementContext.StatementName);
                }
                catch (Exception ex)
                {
                    Log.Error("Error removing variable '" + createDesc.VariableName + "': " + ex.Message);
                }
            }));

            var stopMethod = new ProxyEPStatementStopMethod(() => { });

            var      variableMetaData = services.VariableService.GetVariableMetaData(createDesc.VariableName);
            Viewable outputView;
            var      eventType = CreateVariableView.GetEventType(
                statementContext.StatementId, services.EventAdapterService, variableMetaData);
            var contextFactory =
                new StatementAgentInstanceFactoryCreateVariable(
                    createDesc, _statementSpec, statementContext, services, variableMetaData, eventType);

            statementContext.StatementAgentInstanceFactory = contextFactory;

            if (_statementSpec.OptionalContextName != null)
            {
                var mergeView = new ContextMergeView(eventType);
                outputView = mergeView;
                var statement =
                    new ContextManagedStatementCreateVariableDesc(_statementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(
                    _statementSpec.OptionalContextName, statement, isRecoveringResilient);

                var contextManagementService = services.ContextManagementService;
                destroyMethod.AddCallback(new ProxyDestroyCallback(() => contextManagementService.DestroyedStatement(
                                                                       _statementSpec.OptionalContextName, statementContext.StatementName,
                                                                       statementContext.StatementId)));
            }
            else
            {
                var resultOfStart =
                    (StatementAgentInstanceFactoryCreateVariableResult)
                    contextFactory.NewContext(GetDefaultAgentInstanceContext(statementContext), isRecoveringResilient);
                outputView = resultOfStart.FinalView;

                if (statementContext.StatementExtensionServicesContext != null &&
                    statementContext.StatementExtensionServicesContext.StmtResources != null)
                {
                    var holder =
                        statementContext.StatementExtensionServicesContext.ExtractStatementResourceHolder(resultOfStart);
                    statementContext.StatementExtensionServicesContext.StmtResources.Unpartitioned = holder;
                    statementContext.StatementExtensionServicesContext.PostProcessStart(resultOfStart, isRecoveringResilient);
                }
            }

            services.StatementVariableRefService.AddReferences(
                statementContext.StatementName, Collections.SingletonList(createDesc.VariableName), null);
            return(new EPStatementStartResult(outputView, stopMethod, destroyMethod));
        }
 public override AggregationMethodFactory ValidateAggregationChild(ExprValidationContext validationContext)
 {
     return(ValidateAggregationInternal(validationContext, null));
 }
 public AggregationMethodFactory ValidateAggregationParamsWBinding(ExprValidationContext validationContext, TableMetadataColumnAggregation tableAccessColumn)
 {
     return(ValidateAggregationInternal(validationContext, tableAccessColumn));
 }
Пример #28
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (Script.ParameterNames.Length != 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.Length,
                        Parameters.Count));
            }

            if (!validationContext.StatementCompileTimeService.Configuration.Compiler.Scripts.IsEnabled) {
                throw new ExprValidationException("Script compilation has been disabled by configuration");
            }

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

            // set up map of input parameter names and evaluators
            var forges = new ExprForge[Script.ParameterNames.Length];
            for (var i = 0; i < Script.ParameterNames.Length; i++) {
                forges[i] = validatedParameters[i].Forge;
            }

            Parameters = validatedParameters;

            // Compile script
            var parameterTypes = ExprNodeUtilityQuery.GetExprResultTypes(forges);
            var dialect = Script.OptionalDialect ?? _defaultDialect;
            var compiled = CompileScript(
                dialect,
                Script.Name,
                Script.Expression,
                Script.ParameterNames,
                parameterTypes,
                Script.CompiledBuf,
                validationContext.ImportService,
                validationContext.ScriptCompiler);

            // Determine declared return type
            var declaredReturnType = GetDeclaredReturnType(Script.OptionalReturnTypeName, validationContext);
            if (Script.IsOptionalReturnTypeIsArray && declaredReturnType != null) {
                declaredReturnType = TypeHelper.GetArrayType(declaredReturnType);
            }

            Type returnType;
            if (compiled.KnownReturnType == null && Script.OptionalReturnTypeName == null) {
                returnType = typeof(object);
            }
            else if (compiled.KnownReturnType != null) {
                if (declaredReturnType == null) {
                    returnType = compiled.KnownReturnType;
                }
                else {
                    var knownReturnType = 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);
            }

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

            _scriptDescriptor = new ScriptDescriptorCompileTime(
                Script.OptionalDialect,
                Script.Name,
                Script.Expression,
                Script.ParameterNames,
                Parameters.ToArray(),
                returnType,
                _defaultDialect);
            return null;
        }
Пример #29
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            _length     = ChildNodes.Count;
            _evaluators = ExprNodeUtility.GetEvaluators(ChildNodes);

            // Can be an empty array with no content
            if (ChildNodes.Count == 0)
            {
                _arrayReturnType = typeof(Object);
                _constantResult  = new Object[0];
                return(null);
            }

            var comparedTypes = new List <Type>();

            for (int i = 0; i < _length; i++)
            {
                comparedTypes.Add(_evaluators[i].ReturnType);
            }

            // Determine common denominator type
            try {
                _arrayReturnType = TypeHelper.GetCommonCoercionType(comparedTypes.ToArray());

                // Determine if we need to coerce numbers when one type doesn't match any other type
                if (_arrayReturnType.IsNumeric())
                {
                    _mustCoerce = false;
                    foreach (var comparedType in comparedTypes)
                    {
                        if (comparedType != _arrayReturnType)
                        {
                            _mustCoerce = true;
                        }
                    }
                    if (_mustCoerce)
                    {
                        _coercer = CoercerFactory.GetCoercer(null, _arrayReturnType);
                    }
                }
            }
            catch (CoercionException)
            {
                // expected, such as mixing String and int values, or classes (not boxed) and primitives
                // use Object[] in such cases
            }
            if (_arrayReturnType == null)
            {
                _arrayReturnType = typeof(Object);
            }

            // Determine if we are dealing with constants only
            var results = new Object[_length];
            int index   = 0;

            foreach (ExprNode child in ChildNodes)
            {
                if (!child.IsConstantResult)
                {
                    results = null;  // not using a constant result
                    break;
                }
                results[index] = _evaluators[index].Evaluate(new EvaluateParams(null, false, validationContext.ExprEvaluatorContext));
                index++;
            }

            // Copy constants into array and coerce, if required
            if (results != null)
            {
                var asArray = Array.CreateInstance(_arrayReturnType, _length);
                _constantResult = asArray;

                for (int i = 0; i < _length; i++)
                {
                    if (_mustCoerce)
                    {
                        var boxed = results[i];
                        if (boxed != null)
                        {
                            Object coercedResult = _coercer.Invoke(boxed);
                            asArray.SetValue(coercedResult, i);
                        }
                    }
                    else
                    {
                        asArray.SetValue(results[i], i);
                    }
                }
            }

            return(null);
        }
Пример #30
0
        private CountMinSketchSpecForge ValidateSpecification(ExprValidationContext exprValidationContext)
        {
            // default specification
            CountMinSketchSpecHashes hashes = new CountMinSketchSpecHashes(DEFAULT_EPS_OF_TOTAL_COUNT, DEFAULT_CONFIDENCE, DEFAULT_SEED);
            CountMinSketchSpecForge  spec   = new CountMinSketchSpecForge(hashes, null, DEFAULT_AGENT);

            // no parameters
            if (this.ChildNodes.Length == 0)
            {
                return(spec);
            }

            // check expected parameter type: a json object
            if (this.ChildNodes.Length > 1 || !(this.ChildNodes[0] is ExprConstantNode))
            {
                throw GetDeclaredWrongParameterExpr();
            }

            ExprConstantNode constantNode = (ExprConstantNode)this.ChildNodes[0];
            object           value        = constantNode.ConstantValue;

            if (!(value is IDictionary <string, object>))
            {
                throw GetDeclaredWrongParameterExpr();
            }

            // define what to populate
            PopulateFieldWValueDescriptor[] descriptors = new PopulateFieldWValueDescriptor[] {
                new PopulateFieldWValueDescriptor(
                    NAME_EPS_OF_TOTAL_COUNT,
                    typeof(double?),
                    spec.HashesSpec.GetType(),
                    value => {
                    if (value != null)
                    {
                        spec.HashesSpec.EpsOfTotalCount = value.AsDouble();
                    }
                },
                    true),
                new PopulateFieldWValueDescriptor(
                    NAME_CONFIDENCE,
                    typeof(double?),
                    spec.HashesSpec.GetType(),
                    value => {
                    if (value != null)
                    {
                        spec.HashesSpec.Confidence = value.AsDouble();
                    }
                },
                    true),
                new PopulateFieldWValueDescriptor(
                    NAME_SEED,
                    typeof(int?),
                    spec.HashesSpec.GetType(),
                    value => {
                    if (value != null)
                    {
                        spec.HashesSpec.Seed = value.AsInt32();
                    }
                },
                    true),
                new PopulateFieldWValueDescriptor(
                    NAME_TOPK,
                    typeof(int?),
                    spec.GetType(),
                    value => {
                    if (value != null)
                    {
                        spec.TopkSpec = (int?)value;
                    }
                },
                    true),
                new PopulateFieldWValueDescriptor(
                    NAME_AGENT,
                    typeof(string),
                    spec.GetType(),
                    value => {
                    if (value != null)
                    {
                        CountMinSketchAgentForge transform;
                        try {
                            var transformClass = exprValidationContext.ImportService.ResolveClass(
                                (string)value,
                                false,
                                ExtensionClassEmpty.INSTANCE);
                            transform = TypeHelper.Instantiate <CountMinSketchAgentForge>(transformClass);
                        }
                        catch (Exception e) {
                            throw new ExprValidationException("Failed to instantiate agent provider: " + e.Message, e);
                        }

                        spec.Agent = transform;
                    }
                },
                    true),
            };

            // populate from json, validates incorrect names, coerces types, instantiates transform
            PopulateUtil.PopulateSpecCheckParameters(descriptors, (IDictionary <string, object>)value, spec, ExprNodeOrigin.AGGPARAM, exprValidationContext);

            return(spec);
        }