예제 #1
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);
            }

            var childType = first.Forge.EvaluationType;
            var serde = validationContext.SerdeResolver.SerdeForAggregationDistinct(childType, validationContext.StatementRawInfo);
            var distinctValueSerde = isDistinct ? serde : null;
            return new AggregationForgeFactoryNth(this, childType, serde, distinctValueSerde, size);
        }
예제 #2
0
        public void ValidatePositionals(ExprValidationContext validationContext)
        {
            ExprAggregateNodeParamDesc paramDesc = ExprAggregateNodeUtil.GetValidatePositionalParams(ChildNodes, true);
            if (validationContext.StatementRawInfo.StatementType == StatementType.CREATE_TABLE &&
                (paramDesc.OptLocalGroupBy != null || paramDesc.OptionalFilter != null)) {
                throw new ExprValidationException(
                    "The 'group_by' and 'filter' parameter is not allowed in create-table statements");
            }

            optionalAggregateLocalGroupByDesc = paramDesc.OptLocalGroupBy;
            optionalFilter = paramDesc.OptionalFilter;
            if (optionalAggregateLocalGroupByDesc != null) {
                ExprNodeUtilityValidate.ValidateNoSpecialsGroupByExpressions(
                    optionalAggregateLocalGroupByDesc.PartitionExpressions);
            }

            if (optionalFilter != null) {
                ExprNodeUtilityValidate.ValidateNoSpecialsGroupByExpressions(new[] {optionalFilter});
            }

            if (optionalFilter != null && IsFilterExpressionAsLastParameter) {
                if (paramDesc.PositionalParams.Length > 1) {
                    throw new ExprValidationException("Only a single filter expression can be provided");
                }

                positionalParams = ExprNodeUtilityMake.AddExpression(paramDesc.PositionalParams, optionalFilter);
            }
            else {
                positionalParams = paramDesc.PositionalParams;
            }
        }
예제 #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 override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            Type[] parameterTypes = new Type[positionalParams.Length];
            object[] constant = new object[positionalParams.Length];
            bool[] isConstant = new bool[positionalParams.Length];
            ExprNode[] expressions = new ExprNode[positionalParams.Length];

            int count = 0;
            bool hasDataWindows = true;
            foreach (ExprNode child in positionalParams) {
                if (child.Forge.ForgeConstantType == ExprForgeConstantType.COMPILETIMECONST) {
                    isConstant[count] = true;
                    constant[count] = child.Forge.ExprEvaluator.Evaluate(null, true, null);
                }

                parameterTypes[count] = child.Forge.EvaluationType;
                expressions[count] = child;

                if (!ExprNodeUtilityAggregation.HasRemoveStreamForAggregations(
                    child,
                    validationContext.StreamTypeService,
                    validationContext.IsResettingAggregations)) {
                    hasDataWindows = false;
                }

                if (child is ExprWildcard) {
                    ExprAggMultiFunctionUtil.CheckWildcardNotJoinOrSubquery(
                        validationContext.StreamTypeService,
                        functionName);
                    parameterTypes[count] = validationContext.StreamTypeService.EventTypes[0].UnderlyingType;
                    isConstant[count] = false;
                    constant[count] = null;
                }

                count++;
            }

            LinkedHashMap<string, IList<ExprNode>> namedParameters = null;
            if (optionalFilter != null) {
                namedParameters = new LinkedHashMap<string, IList<ExprNode>>();
                namedParameters.Put("filter", Collections.SingletonList(optionalFilter));
                positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter);
            }

            AggregationFunctionValidationContext context = new AggregationFunctionValidationContext(
                parameterTypes,
                isConstant,
                constant,
                base.IsDistinct,
                hasDataWindows,
                expressions,
                namedParameters);
            try {
                // the aggregation function factory is transient, obtain if not provided
                if (aggregationFunctionForge == null) {
                    aggregationFunctionForge =
                        validationContext.ImportService.ResolveAggregationFunction(functionName);
                }

                aggregationFunctionForge.Validate(context);
            }
            catch (Exception ex) {
                throw new ExprValidationException(
                    "Plug-in aggregation function '" + functionName + "' failed validation: " + ex.Message,
                    ex);
            }

            AggregationFunctionMode mode = aggregationFunctionForge.AggregationFunctionMode;
            if (mode == null) {
                throw new ExprValidationException("Aggregation function forge returned a null value for mode");
            }

            if (mode is AggregationFunctionModeManaged) {
                if (positionalParams.Length > 2) {
                    throw new ExprValidationException(
                        "Aggregation function forge single-value mode requires zero, one or two parameters");
                }
            }
            else if (mode is AggregationFunctionModeMultiParam || mode is AggregationFunctionModeCodeGenerated) {
            }
            else {
                throw new ExprValidationException("Aggregation function forge returned an unrecognized mode " + mode);
            }

            return new AggregationMethodFactoryPluginMethod(this, aggregationFunctionForge, mode);
        }
        private AggregationLinearFactoryDesc HandleNonIntoTable(
            ExprNode[] childNodes,
            AggregationAccessorLinearType?stateType,
            ExprValidationContext validationContext)
        {
            var       streamTypeService = validationContext.StreamTypeService;
            int       streamNum;
            Type      resultType;
            ExprForge forge;
            ExprNode  evaluatorIndex = null;
            bool      istreamOnly;
            EventType containedType;
            Type      scalarCollectionComponentType = null;

            // validate wildcard use
            var isWildcard = childNodes.Length == 0 || childNodes.Length > 0 && childNodes[0] is ExprWildcard;

            if (isWildcard)
            {
                ExprAggMultiFunctionUtil.ValidateWildcardStreamNumbers(validationContext.StreamTypeService, stateType?.GetNameInvariant());
                streamNum     = 0;
                containedType = streamTypeService.EventTypes[0];
                resultType    = containedType.UnderlyingType;
                var tableMetadataX = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType);
                forge       = ExprNodeUtilityMake.MakeUnderlyingForge(0, resultType, tableMetadataX);
                istreamOnly = GetIstreamOnly(streamTypeService, 0);
                if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams)
                {
                    throw MakeUnboundValidationEx(stateType);
                }
            }
            else if (childNodes.Length > 0 && childNodes[0] is ExprStreamUnderlyingNode)
            {
                // validate "stream.*"
                streamNum   = ExprAggMultiFunctionUtil.ValidateStreamWildcardGetStreamNum(childNodes[0]);
                istreamOnly = GetIstreamOnly(streamTypeService, streamNum);
                if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams)
                {
                    throw MakeUnboundValidationEx(stateType);
                }

                var type = streamTypeService.EventTypes[streamNum];
                containedType = type;
                resultType    = type.UnderlyingType;
                var tableMetadataX = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(type);
                forge = ExprNodeUtilityMake.MakeUnderlyingForge(streamNum, resultType, tableMetadataX);
            }
            else
            {
                // validate when neither wildcard nor "stream.*"
                var child   = childNodes[0];
                var streams = ExprNodeUtilityQuery.GetIdentStreamNumbers(child);
                if (streams.IsEmpty() || (streams.Count > 1))
                {
                    throw new ExprValidationException(
                              GetErrorPrefix(stateType) +
                              " requires that any child expressions evaluate properties of the same stream; Use 'firstever' or 'lastever' or 'nth' instead");
                }

                streamNum   = streams.First();
                istreamOnly = GetIstreamOnly(streamTypeService, streamNum);
                if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams)
                {
                    throw MakeUnboundValidationEx(stateType);
                }

                resultType = childNodes[0].Forge.EvaluationType;
                forge      = childNodes[0].Forge;
                if (streamNum >= streamTypeService.EventTypes.Length)
                {
                    containedType = streamTypeService.EventTypes[0];
                }
                else
                {
                    containedType = streamTypeService.EventTypes[streamNum];
                }

                scalarCollectionComponentType = resultType;
            }

            if (childNodes.Length > 1)
            {
                if (stateType == AggregationAccessorLinearType.WINDOW)
                {
                    throw new ExprValidationException(GetErrorPrefix(stateType) + " does not accept an index expression; Use 'first' or 'last' instead");
                }

                evaluatorIndex = childNodes[1];
                var indexResultType = evaluatorIndex.Forge.EvaluationType;
                if (indexResultType != typeof(int?) && indexResultType != typeof(int))
                {
                    throw new ExprValidationException(GetErrorPrefix(stateType) + " requires an index expression that returns an integer value");
                }
            }

            // determine accessor
            AggregationAccessorForge accessor;

            if (evaluatorIndex != null)
            {
                var       isFirst  = stateType == AggregationAccessorLinearType.FIRST;
                var       constant = -1;
                ExprForge forgeIndex;
                if (evaluatorIndex.Forge.ForgeConstantType.IsCompileTimeConstant)
                {
                    constant   = evaluatorIndex.Forge.ExprEvaluator.Evaluate(null, true, null).AsInt32();
                    forgeIndex = null;
                }
                else
                {
                    forgeIndex = evaluatorIndex.Forge;
                }

                accessor = new AggregationAccessorFirstLastIndexWEvalForge(streamNum, forge, forgeIndex, constant, isFirst);
            }
            else
            {
                if (stateType == AggregationAccessorLinearType.FIRST)
                {
                    accessor = new AggregationAccessorFirstWEvalForge(streamNum, forge);
                }
                else if (stateType == AggregationAccessorLinearType.LAST)
                {
                    accessor = new AggregationAccessorLastWEvalForge(streamNum, forge);
                }
                else if (stateType == AggregationAccessorLinearType.WINDOW)
                {
                    accessor = new AggregationAccessorWindowWEvalForge(streamNum, forge, resultType);
                }
                else
                {
                    throw new IllegalStateException("Access type is undefined or not known as code '" + stateType + "'");
                }
            }

            var accessorResultType = resultType;

            if (stateType == AggregationAccessorLinearType.WINDOW)
            {
                accessorResultType = TypeHelper.GetArrayType(resultType);
            }

            var isFafWindow   = streamTypeService.IsOnDemandStreams && stateType == AggregationAccessorLinearType.WINDOW;
            var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType);

            if (tableMetadata == null && !isFafWindow && (istreamOnly || streamTypeService.IsOnDemandStreams))
            {
                if (optionalFilter != null)
                {
                    positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter);
                }

                var serde = validationContext.SerdeResolver.SerdeForAggregation(accessorResultType, validationContext.StatementRawInfo);
                AggregationForgeFactory factoryX = new AggregationForgeFactoryFirstLastUnbound(this, accessorResultType, optionalFilter != null, serde);
                return(new AggregationLinearFactoryDesc(factoryX, containedType, scalarCollectionComponentType, streamNum));
            }

            var stateKey = new AggregationStateKeyWStream(
                streamNum,
                containedType,
                AggregationStateTypeWStream.DATAWINDOWACCESS_LINEAR,
                ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY,
                optionalFilter);

            var optionalFilterForge = optionalFilter == null ? null : optionalFilter.Forge;
            AggregationStateFactoryForge stateFactory = new AggregationStateLinearForge(this, streamNum, optionalFilterForge);

            var factory = new AggregationForgeFactoryAccessLinear(
                this,
                accessor,
                accessorResultType,
                stateKey,
                stateFactory,
                AggregationAgentDefault.INSTANCE,
                containedType);
            var enumerationType = scalarCollectionComponentType == null ? containedType : null;

            var serdeForgables = SerdeEventTypeUtility.Plan(
                containedType,
                validationContext.StatementRawInfo,
                validationContext.SerdeEventTypeRegistry,
                validationContext.SerdeResolver);

            validationContext.AdditionalForgeables.AddAll(serdeForgables);

            return(new AggregationLinearFactoryDesc(factory, enumerationType, scalarCollectionComponentType, streamNum));
        }
예제 #6
0
        public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext)
        {
            if (this.positionalParams.Length == 0) {
                throw new ExprValidationException(
                    "The rate aggregation function minimally requires a numeric constant or expression as a parameter.");
            }

            // handle "ever"
            ExprNode first = this.positionalParams[0];
            if (first.Forge.ForgeConstantType.IsCompileTimeConstant) {
                string messageX =
                    "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, null);
                    intervalTime =
                        validationContext.ImportService.TimeAbacus.DeltaForSecondsDouble(secInterval);
                }
                else if (ExprNodeUtilityQuery.IsConstant(first)) {
                    if (!first.Forge.EvaluationType.IsNumeric()) {
                        throw new ExprValidationException(messageX);
                    }

                    var num = first.Forge.ExprEvaluator.Evaluate(null, true, null);
                    intervalTime = validationContext.ImportService.TimeAbacus.DeltaForSecondsNumber(num);
                }
                else {
                    throw new ExprValidationException(messageX);
                }

                if (optionalFilter == null) {
                    this.positionalParams = ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY;
                }
                else {
                    this.positionalParams = new ExprNode[] {optionalFilter};
                }

                return new AggregationForgeFactoryRate(this, true, intervalTime, validationContext.ImportService.TimeAbacus);
            }

            string message =
                "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.Forge.EvaluationType.GetBoxedType();
            if (boxedParamOne != typeof(long?)) {
                throw new ExprValidationException(message);
            }

            if (first.Forge.ForgeConstantType.IsConstant) {
                throw new ExprValidationException(message);
            }

            if (first is ExprTimestampNode) {
                throw new ExprValidationException(
                    "The rate aggregation function does not allow the current runtime timestamp as a parameter");
            }

            if (this.positionalParams.Length > 1) {
                if (!this.positionalParams[1].Forge.EvaluationType.IsNumeric()) {
                    throw new ExprValidationException(
                        "The rate aggregation function accepts an expression returning a numeric value to accumulate as an optional second parameter");
                }
            }

            bool hasDataWindows = ExprNodeUtilityAggregation.HasRemoveStreamForAggregations(
                first,
                validationContext.StreamTypeService,
                validationContext.IsResettingAggregations);
            if (!hasDataWindows) {
                throw new ExprValidationException(
                    "The rate aggregation function in the timestamp-property notation requires data windows");
            }

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

            return new AggregationForgeFactoryRate(this, false, -1, validationContext.ImportService.TimeAbacus);
        }