Пример #1
0
        public override EventType[] GetAddStreamTypes(
            string enumMethodUsedName,
            IList<string> goesToNames,
            EventType inputEventType,
            Type collectionComponentType,
            IList<ExprDotEvalParam> bodiesAndParameters,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            EventType evalEventType;
            if (inputEventType == null) {
                evalEventType = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    goesToNames[1],
                    collectionComponentType,
                    statementRawInfo,
                    services);
            }
            else {
                evalEventType = inputEventType;
            }

            var initializationType = bodiesAndParameters[0].BodyForge.EvaluationType;
            EventType typeResult = ExprDotNodeUtility.MakeTransientOAType(
                enumMethodUsedName,
                goesToNames[0],
                initializationType,
                statementRawInfo,
                services);

            return new[] {typeResult, evalEventType};
        }
Пример #2
0
        public override EventType[] GetAddStreamTypes(
            string enumMethodUsedName,
            IList<string> goesToNames,
            EventType inputEventType,
            Type collectionComponentType,
            IList<ExprDotEvalParam> bodiesAndParameters,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            EventType firstParamType;
            if (inputEventType == null) {
                firstParamType = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    goesToNames[0],
                    collectionComponentType,
                    statementRawInfo,
                    services);
            }
            else {
                firstParamType = inputEventType;
            }

            if (goesToNames.Count == 1) {
                return new EventType[] {firstParamType};
            }

            var indexEventType = ExprDotNodeUtility.MakeTransientOAType(
                enumMethodUsedName,
                goesToNames[1],
                typeof(int),
                statementRawInfo,
                services);
            return new EventType[] {firstParamType, indexEventType};
        }
Пример #3
0
        public override EventType[] GetAddStreamTypes(
            string enumMethodUsedName,
            IList <string> goesToNames,
            EventType inputEventType,
            Type collectionComponentType,
            IList <ExprDotEvalParam> bodiesAndParameters,
            EventAdapterService eventAdapterService)
        {
            EventType evalEventType;

            if (inputEventType == null)
            {
                evalEventType = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName, goesToNames[1], collectionComponentType, eventAdapterService);
            }
            else
            {
                evalEventType = inputEventType;
            }

            Type      initializationType = bodiesAndParameters[0].BodyEvaluator.ReturnType;
            EventType typeResult         = ExprDotNodeUtility.MakeTransientOAType(
                enumMethodUsedName, goesToNames[0], initializationType, eventAdapterService);

            return(new EventType[]
            {
                typeResult,
                evalEventType
            });
        }
Пример #4
0
            public EnumForgeLambdaDesc GetLambdaStreamTypesForParameter(int parameterNum)
            {
                var desc = _footprint.Parameters[parameterNum];
                if (desc.LambdaParamNum == 0) {
                    return new EnumForgeLambdaDesc(new EventType[0], new string[0]);
                }

                var param = _parameters[parameterNum];
                if (!(param is ExprLambdaGoesNode)) {
                    throw new IllegalStateException("Parameter " + parameterNum + " is not a lambda parameter");
                }

                var goes = (ExprLambdaGoesNode) param;
                var goesToNames = goes.GoesToNames;

                // we allocate types for scalar-value-input and index-lambda-parameter-type; for event-input we use the existing input event type
                var types = new EventType[desc.LambdaParamNum];
                var names = new string[desc.LambdaParamNum];
                for (var i = 0; i < types.Length; i++) {
                    // obtain lambda parameter type
                    var lambdaParamType = _mode.LambdaParameters.Invoke(new EnumMethodLambdaParameterDescriptor(parameterNum, i));

                    if (lambdaParamType is EnumMethodLambdaParameterTypeValue) {
                        if (_inputEventType == null) {
                            types[i] = ExprDotNodeUtility.MakeTransientOAType(_enumMethodUsedName, goesToNames[i], _collectionComponentType, _raw, _services);
                        }
                        else {
                            types[i] = _inputEventType;
                        }
                    }
                    else if (lambdaParamType is EnumMethodLambdaParameterTypeIndex || lambdaParamType is EnumMethodLambdaParameterTypeSize) {
                        types[i] = ExprDotNodeUtility.MakeTransientOAType(_enumMethodUsedName, goesToNames[i], typeof(int), _raw, _services);
                    }
                    else if (lambdaParamType is EnumMethodLambdaParameterTypeStateGetter) {
                        var getter = (EnumMethodLambdaParameterTypeStateGetter) lambdaParamType;
                        types[i] = ExprDotNodeUtility.MakeTransientOAType(_enumMethodUsedName, goesToNames[i], getter.Type, _raw, _services);
                    }
                    else {
                        throw new UnsupportedOperationException("Unrecognized lambda parameter type " + lambdaParamType);
                    }

                    if (types[i] == _inputEventType) {
                        names[i] = goesToNames[i];
                    }
                    else {
                        names[i] = types[i].Name;
                    }
                }

                return new EnumForgeLambdaDesc(types, names);
            }
Пример #5
0
        public override EnumForgeDescFactory GetForgeFactory(
            DotMethodFP footprint,
            IList <ExprNode> parameters,
            EnumMethodEnum enumMethod,
            string enumMethodUsedName,
            EventType inputEventType,
            Type collectionComponentType,
            ExprValidationContext validationContext)
        {
            var goesNode      = (ExprLambdaGoesNode)parameters[1];
            var numParameters = goesNode.GoesToNames.Count;
            var firstName     = goesNode.GoesToNames[0];
            var secondName    = goesNode.GoesToNames[1];

            IDictionary <string, object> fields = new Dictionary <string, object>();
            var initializationType = parameters[0].Forge.EvaluationType;

            fields.Put(firstName, initializationType);
            if (inputEventType == null)
            {
                fields.Put(secondName, collectionComponentType);
            }

            if (numParameters > 2)
            {
                fields.Put(goesNode.GoesToNames[2], typeof(int));
                if (numParameters > 3)
                {
                    fields.Put(goesNode.GoesToNames[3], typeof(int));
                }
            }

            var evalEventType = ExprDotNodeUtility.MakeTransientOAType(
                enumMethodUsedName,
                fields,
                validationContext.StatementRawInfo,
                validationContext.StatementCompileTimeService);

            if (inputEventType == null)
            {
                return(new EnumForgeDescFactoryAggregateScalar(evalEventType));
            }

            return(new EnumForgeDescFactoryAggregateEvent(evalEventType, inputEventType, secondName, numParameters));
        }
Пример #6
0
        public override EventType[] GetAddStreamTypes(
            string enumMethodUsedName,
            IList <string> goesToNames,
            EventType inputEventType,
            Type collectionComponentType,
            IList <ExprDotEvalParam> bodiesAndParameters,
            EventAdapterService eventAdapterService)
        {
            EventType firstParamType;

            if (inputEventType == null)
            {
                firstParamType = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName, goesToNames[0], collectionComponentType, eventAdapterService);
            }
            else
            {
                firstParamType = inputEventType;
            }

            if (goesToNames.Count == 1)
            {
                return(new EventType[]
                {
                    firstParamType
                });
            }

            ObjectArrayEventType indexEventType = ExprDotNodeUtility.MakeTransientOAType(
                enumMethodUsedName, goesToNames[1], typeof(int), eventAdapterService);

            return(new EventType[]
            {
                firstParamType,
                indexEventType
            });
        }
Пример #7
0
        public override EnumForgeDescFactory GetForgeFactory(
            DotMethodFP footprint,
            IList <ExprNode> parameters,
            EnumMethodEnum enumMethod,
            string enumMethodUsedName,
            EventType inputEventType,
            Type collectionComponentType,
            ExprValidationContext validationContext)
        {
            if (parameters.IsEmpty())
            {
                var typeX = InitAndNoParamsReturnType(inputEventType, collectionComponentType);
                return(new ThreeFormNoParamFactory(typeX, NoParamsForge(enumMethod, typeX, validationContext.StatementCompileTimeService)));
            }

            var goesNode    = (ExprLambdaGoesNode)parameters[0];
            var goesToNames = goesNode.GoesToNames;

            if (inputEventType != null)
            {
                var streamName = goesToNames[0];
                if (goesToNames.Count == 1)
                {
                    return(new ThreeFormEventPlainFactory(
                               InitAndSingleParamReturnType(inputEventType, collectionComponentType),
                               inputEventType,
                               streamName,
                               SingleParamEventPlain(enumMethod)));
                }

                IDictionary <string, object> fieldsX = new LinkedHashMap <string, object>();
                fieldsX.Put(goesToNames[1], typeof(int?));
                if (goesToNames.Count > 2)
                {
                    fieldsX.Put(goesToNames[2], typeof(int?));
                }

                var fieldType = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    fieldsX,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);
                return(new ThreeFormEventPlusFactory(
                           InitAndSingleParamReturnType(inputEventType, collectionComponentType),
                           inputEventType,
                           streamName,
                           fieldType,
                           goesToNames.Count,
                           SingleParamEventPlus(enumMethod)));
            }

            var fields = new LinkedHashMap <string, object>();

            fields.Put(goesToNames[0], collectionComponentType);
            if (goesToNames.Count > 1)
            {
                fields.Put(goesToNames[1], typeof(int?));
            }

            if (goesToNames.Count > 2)
            {
                fields.Put(goesToNames[2], typeof(int?));
            }

            var type = ExprDotNodeUtility.MakeTransientOAType(
                enumMethodUsedName,
                fields,
                validationContext.StatementRawInfo,
                validationContext.StatementCompileTimeService);

            return(new ThreeFormScalarFactory(
                       InitAndSingleParamReturnType(inputEventType, collectionComponentType),
                       type,
                       goesToNames.Count,
                       SingleParamScalar(enumMethod)));
        }
Пример #8
0
        public override EnumForgeDescFactory GetForgeFactory(
            DotMethodFP footprint,
            IList <ExprNode> parameters,
            EnumMethodEnum enumMethod,
            string enumMethodUsedName,
            EventType inputEventType,
            Type collectionComponentType,
            ExprValidationContext validationContext)
        {
            if (parameters.Count < 2)
            {
                throw new IllegalStateException();
            }

            EPType             returnType   = ReturnType(inputEventType, collectionComponentType);
            ExprLambdaGoesNode lambdaFirst  = (ExprLambdaGoesNode)parameters[0];
            ExprLambdaGoesNode lambdaSecond = (ExprLambdaGoesNode)parameters[1];

            if (lambdaFirst.GoesToNames.Count != lambdaSecond.GoesToNames.Count)
            {
                throw new ExprValidationException(
                          "Enumeration method '" + enumMethodUsedName + "' expected the same number of parameters for both the key and the value expression");
            }

            int numParameters = lambdaFirst.GoesToNames.Count;

            if (inputEventType != null)
            {
                string streamNameFirst  = lambdaFirst.GoesToNames[0];
                string streamNameSecond = lambdaSecond.GoesToNames[0];
                if (numParameters == 1)
                {
                    return(new TwoLambdaThreeFormEventPlainFactory(inputEventType, streamNameFirst, streamNameSecond, returnType, TwoParamEventPlain()));
                }

                IDictionary <string, object> fieldsFirst  = new Dictionary <string, object>();
                IDictionary <string, object> fieldsSecond = new Dictionary <string, object>();
                fieldsFirst.Put(lambdaFirst.GoesToNames[1], typeof(int?));
                fieldsSecond.Put(lambdaSecond.GoesToNames[1], typeof(int?));
                if (numParameters > 2)
                {
                    fieldsFirst.Put(lambdaFirst.GoesToNames[2], typeof(int?));
                    fieldsSecond.Put(lambdaSecond.GoesToNames[2], typeof(int?));
                }

                ObjectArrayEventType typeFirst = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    fieldsFirst,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);
                ObjectArrayEventType typeSecond = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    fieldsSecond,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);
                return(new TwoLambdaThreeFormEventPlusFactory(
                           inputEventType,
                           streamNameFirst,
                           streamNameSecond,
                           typeFirst,
                           typeSecond,
                           lambdaFirst.GoesToNames.Count,
                           returnType,
                           TwoParamEventPlus()));
            }
            else
            {
                IDictionary <string, object> fieldsFirst  = new Dictionary <string, object>();
                IDictionary <string, object> fieldsSecond = new Dictionary <string, object>();
                fieldsFirst.Put(lambdaFirst.GoesToNames[0], collectionComponentType);
                fieldsSecond.Put(lambdaSecond.GoesToNames[0], collectionComponentType);
                if (numParameters > 1)
                {
                    fieldsFirst.Put(lambdaFirst.GoesToNames[1], typeof(int?));
                    fieldsSecond.Put(lambdaSecond.GoesToNames[1], typeof(int?));
                }

                if (numParameters > 2)
                {
                    fieldsFirst.Put(lambdaFirst.GoesToNames[2], typeof(int?));
                    fieldsSecond.Put(lambdaSecond.GoesToNames[2], typeof(int?));
                }

                ObjectArrayEventType typeFirst = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    fieldsFirst,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);
                ObjectArrayEventType typeSecond = ExprDotNodeUtility.MakeTransientOAType(
                    enumMethodUsedName,
                    fieldsSecond,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);

                return(new TwoLambdaThreeFormScalarFactory(
                           typeFirst,
                           typeSecond,
                           lambdaFirst.GoesToNames.Count,
                           returnType,
                           TwoParamScalar()));
            }
        }
Пример #9
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            this.exprValidationContext = validationContext;

            var prototype = PrototypeWVisibility;
            if (prototype.IsAlias) {
                if (!ChainParameters.IsEmpty()) {
                    throw new ExprValidationException("Expression '" + prototype.Name + " is an expression-alias and does not allow parameters");
                }
                try {
                    ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.ALIASEXPRBODY,
                        ExpressionBodyCopy,
                        validationContext);
                }
                catch (ExprValidationException ex) {
                    var message = "Failed to validate expression alias '" + prototype.Name + "': " + ex.Message;
                    throw new ExprValidationException(message, ex);
                }

                forge = ExpressionBodyCopy.Forge;
                return null;
            }

            if (forge != null) {
                return null; // already evaluated
            }

            if (ChildNodes.Length > 0) {
                throw new IllegalStateException("Execution node has its own child nodes");
            }

            // validate chain
            IList<ExprNode> validated = new List<ExprNode>();
            foreach (var expr in ChainParameters) {
                validated.Add(
                    ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.DECLAREDEXPRPARAM,
                        expr,
                        validationContext));
            }

            ChainParameters = validated;

            // validate parameter count
            CheckParameterCount();

            // collect event and value (non-event) parameters
            List<int> valueParameters = new List<int>();
            List<int> eventParameters = new List<int>();
            for (int i = 0; i < prototype.ParametersNames.Length; i++) {
                ExprNode parameter = ChainParameters[i];
                if (parameter is ExprWildcard) {
                    if (validationContext.StreamTypeService.EventTypes.Length != 1) {
                        throw new ExprValidationException("Expression '" + prototype.Name + "' only allows a wildcard parameter if there is a single stream available, please use a stream or tag name instead");
                    }
                }
                if (IsEventProviding(parameter, validationContext)) {
                    eventParameters.Add(i);
                } else {
                    valueParameters.Add(i);
                }
            }

            // determine value event type for holding non-event parameter values, if any
            ObjectArrayEventType valueEventType = null;
            List<ExprNode> valueExpressions = new List<ExprNode>(valueParameters.Count);
            if (!valueParameters.IsEmpty()) {
                var valuePropertyTypes = new LinkedHashMap<string, object>();
                foreach (int index in valueParameters) {
                    String name = prototype.ParametersNames[index];
                    ExprNode expr = ChainParameters[index];
                    var result = Boxing.GetBoxedType(expr.Forge.EvaluationType);
                    valuePropertyTypes.Put(name, result);
                    valueExpressions.Add(expr);
                }

                valueEventType = ExprDotNodeUtility.MakeTransientOAType(
                    PrototypeWVisibility.Name,
                    valuePropertyTypes,
                    validationContext.StatementRawInfo,
                    validationContext.StatementCompileTimeService);
            }

            // create context for expression body
            int numEventTypes = eventParameters.Count + (valueEventType == null ? 0 : 1);
            EventType[] eventTypes = new EventType[numEventTypes];
            String[] streamNames = new String[numEventTypes];
            bool[] isIStreamOnly = new bool[numEventTypes];
            ExprEnumerationForge[] eventEnumerationForges = new ExprEnumerationForge[numEventTypes];
            allStreamIdsMatch = true;

            int offsetEventType = 0;
            if (valueEventType != null) {
                offsetEventType = 1;
                eventTypes[0] = valueEventType;
                streamNames[0] = INTERNAL_VALUE_STREAMNAME;
                isIStreamOnly[0] = true;
                allStreamIdsMatch = false;
            }

            bool forceOptionalStream = false;
            foreach (int index in eventParameters) {
                ExprNode parameter = ChainParameters[index];
                streamNames[offsetEventType] = prototype.ParametersNames[index];
                int streamId;
                bool istreamOnlyFlag;
                ExprEnumerationForge forge;

                if (parameter is ExprEnumerationForgeProvider) {
                    ExprEnumerationForgeProvider enumerationForgeProvider = (ExprEnumerationForgeProvider) parameter;
                    ExprEnumerationForgeDesc desc = enumerationForgeProvider.GetEnumerationForge(
                        validationContext.StreamTypeService, validationContext.ContextDescriptor);
                    forge = desc.Forge;
                    streamId = desc.DirectIndexStreamNumber;
                    istreamOnlyFlag = desc.IsIstreamOnly;
                } else {
                    forge = (ExprEnumerationForge) parameter.Forge;
                    istreamOnlyFlag = false;
                    streamId = -1;
                    forceOptionalStream = true; // since they may return null, i.e. subquery returning no row or multiple rows etc.
                }

                isIStreamOnly[offsetEventType] = istreamOnlyFlag;
                eventEnumerationForges[offsetEventType] = forge;
                eventTypes[offsetEventType] = forge.GetEventTypeSingle(validationContext.StatementRawInfo, validationContext.StatementCompileTimeService);

                if (streamId != index) {
                    allStreamIdsMatch = false;
                }
                offsetEventType++;
            }

            var streamTypeService = validationContext.StreamTypeService;
            var optionalStream = forceOptionalStream || streamTypeService.IsOptionalStreams;
            var copyTypes = new StreamTypeServiceImpl(
                eventTypes,
                streamNames,
                isIStreamOnly,
                streamTypeService.IsOnDemandStreams,
                optionalStream);

            copyTypes.RequireStreamNames = true;

            // validate expression body in this context
            try {
                var expressionBodyContext = new ExprValidationContext(copyTypes, validationContext);
                ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.DECLAREDEXPRBODY,
                    ExpressionBodyCopy,
                    expressionBodyContext);
            }
            catch (ExprValidationException ex) {
                var message = "Failed to validate expression declaration '" + prototype.Name + "': " + ex.Message;
                throw new ExprValidationException(message, ex);
            }

            // analyze child node
            var summaryVisitor = new ExprNodeSummaryVisitor();
            ExpressionBodyCopy.Accept(summaryVisitor);
            var isCache = !(summaryVisitor.HasAggregation || summaryVisitor.HasPreviousPrior);
            isCache &= validationContext.StatementCompileTimeService.Configuration.Compiler.Execution
                .IsEnabledDeclaredExprValueCache;

            // determine a suitable evaluation
            var audit = AuditEnum.EXPRDEF.GetAudit(validationContext.Annotations) != null;
            var statementName = validationContext.StatementName;
            if (ExpressionBodyCopy.Forge.ForgeConstantType.IsConstant) {
                // pre-evaluated
                forge = new ExprDeclaredForgeConstant(
                    this,
                    ExpressionBodyCopy.Forge.EvaluationType,
                    prototype,
                    ExpressionBodyCopy.Forge.ExprEvaluator.Evaluate(null, true, null),
                    audit,
                    statementName);
            }
            else if (valueEventType == null &&
                     prototype.ParametersNames.Length == 0 ||
                     allStreamIdsMatch && prototype.ParametersNames.Length == streamTypeService.EventTypes.Length) {
                forge = new ExprDeclaredForgeNoRewrite(
                    this, ExpressionBodyCopy.Forge, isCache, audit, statementName);
            }
            else if (valueEventType == null) {
                forge = new ExprDeclaredForgeRewrite(
                    this, ExpressionBodyCopy.Forge, isCache, eventEnumerationForges, audit, statementName);
            }
            else {
                // cache is always false
                forge = new ExprDeclaredForgeRewriteWValue(
                    this, ExpressionBodyCopy.Forge, false, audit, statementName, eventEnumerationForges, valueEventType, valueExpressions);
            }

            return null;
        }