Пример #1
0
        public override CodegenExpression Codegen(
            InternalEventRouterWriterForge writer,
            CodegenMethodScope parent,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            var method = parent
                         .MakeChild(typeof(InternalEventRouterWriterArrayElement), GetType(), classScope);

            var indexExpr = ExprNodeUtilityCodegen.CodegenEvaluator(
                _indexExpression.Forge,
                method,
                typeof(VariableTriggerWriteArrayElementForge),
                classScope);
            var rhsExpr = ExprNodeUtilityCodegen.CodegenEvaluator(
                _rhsExpression.Forge,
                method,
                typeof(VariableTriggerWriteArrayElementForge),
                classScope);
            var typeWidenerExpr = _widener == null
                                ? ConstantNull()
                                : TypeWidenerFactory.CodegenWidener(_widener, method, GetType(), classScope);

            method.Block
            .DeclareVar <InternalEventRouterWriterArrayElement>("desc", NewInstance(typeof(InternalEventRouterWriterArrayElement)))
            .SetProperty(Ref("desc"), "IndexExpression", indexExpr)
            .SetProperty(Ref("desc"), "RhsExpression", rhsExpr)
            .SetProperty(Ref("desc"), "TypeWidener", typeWidenerExpr)
            .SetProperty(Ref("desc"), "PropertyName", Constant(_propertyName))
            .MethodReturn(Ref("desc"));
            return(LocalMethod(method));
        }
 private static TypeWidener GetWidener(
     int columnNum,
     Type selectClauseType,
     Type parameterType,
     MethodInfo method,
     string statementName,
     string engineURI)
 {
     if (selectClauseType == null || parameterType == null)
     {
         return(null);
     }
     if (selectClauseType == parameterType)
     {
         return(null);
     }
     try
     {
         return(TypeWidenerFactory.GetCheckPropertyAssignType(
                    "Select-Clause Column " + columnNum, selectClauseType, parameterType,
                    "Method Parameter " + columnNum, false, null,
                    statementName, engineURI));
     }
     catch (ExprValidationException e)
     {
         throw new EPException(
                   "Unexpected exception assigning select clause columns to subscriber method " + method + ": " +
                   e.Message, e);
     }
 }
Пример #3
0
 public TypeWidener WidenerFor(string columnName, Type columnType, Type writeablePropertyType, string writeablePropertyName, string statementName, string engineURI)
 {
     //if (columnType == typeof(byte[]) && writeablePropertyType == typeof(ByteBuffer))
     //{
     //    return BYTE_ARRAY_TO_BYTE_BUFFER_COERCER;
     //}
     if (columnType != null && columnType.IsArray && writeablePropertyType.IsGenericCollection())
     {
         return(TypeWidenerFactory.GetArrayToCollectionCoercer(
                    columnType.GetElementType()));
     }
     return(null);
 }
Пример #4
0
        public TypeWidenerSPI WidenerFor(
            string columnName,
            Type columnType,
            Type writeablePropertyType,
            string writeablePropertyName,
            string statementName)
        {
            if (columnType != null && columnType.IsArray && writeablePropertyType.IsGenericCollection()) {
                return TypeWidenerFactory.GetArrayToCollectionCoercer(columnType.GetElementType());
            }

            return null;
        }
Пример #5
0
        public InternalEventRouterDesc GetValidatePreprocessing(EventType eventType, UpdateDesc desc, Attribute[] annotations)
        {
            if (Log.IsDebugEnabled)
            {
                Log.Debug("Validating route preprocessing for type '" + eventType.Name + "'");
            }

            if (!(eventType is EventTypeSPI))
            {
                throw new ExprValidationException("Update statements require the event type to implement the " + typeof(EventTypeSPI) + " interface");
            }

            var eventTypeSPI = (EventTypeSPI)eventType;
            var wideners     = new TypeWidener[desc.Assignments.Count];
            var properties   = new List <String>();

            for (int i = 0; i < desc.Assignments.Count; i++)
            {
                var xxx            = desc.Assignments[i];
                var assignmentPair = ExprNodeUtility.CheckGetAssignmentToProp(xxx.Expression);
                if (assignmentPair == null)
                {
                    throw new ExprValidationException("Missing property assignment expression in assignment number " + i);
                }

                var writableProperty = eventTypeSPI.GetWritableProperty(assignmentPair.First);
                if (writableProperty == null)
                {
                    throw new ExprValidationException("Property '" + assignmentPair.First + "' is not available for write access");
                }

                wideners[i] = TypeWidenerFactory.GetCheckPropertyAssignType(
                    ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(assignmentPair.Second),
                    assignmentPair.Second.ExprEvaluator.ReturnType,
                    writableProperty.PropertyType,
                    assignmentPair.First);
                properties.Add(assignmentPair.First);
            }

            // check copy-able
            var copyMethod = eventTypeSPI.GetCopyMethod(properties.ToArray());

            if (copyMethod == null)
            {
                throw new ExprValidationException("The update-clause requires the underlying event representation to support copy (via Serializable by default)");
            }

            return(new InternalEventRouterDesc(desc, copyMethod, wideners, eventType, annotations));
        }
Пример #6
0
        private CodegenExpression MakeWideners(
            TypeWidenerSPI[] wideners,
            CodegenMethod method,
            CodegenClassScope classScope)
        {
            var init = new CodegenExpression[wideners.Length];
            for (var i = 0; i < init.Length; i++) {
                if (wideners[i] != null) {
                    init[i] = TypeWidenerFactory.CodegenWidener(wideners[i], method, GetType(), classScope);
                }
                else {
                    init[i] = ConstantNull();
                }
            }

            return NewArrayWithInit(typeof(TypeWidener), init);
        }
Пример #7
0
        public override CodegenExpression Make(
            CodegenMethodScope parent,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            CodegenMethod method = parent.MakeChild(typeof(VariableTriggerWriteArrayElement), this.GetType(), classScope);

            method.Block
            .DeclareVar <VariableTriggerWriteArrayElement>("desc", NewInstance(typeof(VariableTriggerWriteArrayElement)))
            .SetProperty(Ref("desc"), "VariableName", Constant(variableName))
            .SetProperty(
                Ref("desc"),
                "IndexExpression",
                ExprNodeUtilityCodegen.CodegenEvaluator(indexExpression, method, typeof(VariableTriggerWriteArrayElementForge), classScope))
            .SetProperty(
                Ref("desc"),
                "TypeWidener",
                widener == null ? ConstantNull() : TypeWidenerFactory.CodegenWidener(widener, method, this.GetType(), classScope))
            .MethodReturn(Ref("desc"));
            return(LocalMethod(method));
        }
        private static SelectExprProcessor InitializeSetterManufactor(
            EventType eventType,
            ICollection <WriteablePropertyDescriptor> writables,
            bool isUsingWildcard,
            StreamTypeService typeService,
            ExprEvaluator[] expressionNodes,
            string[] columnNames,
            Object[] expressionReturnTypes,
            EngineImportService engineImportService,
            EventAdapterService eventAdapterService,
            string statementName)
        {
            var typeWidenerCustomizer  = eventAdapterService.GetTypeWidenerCustomizer(eventType);
            var writablePropertiesList = new List <WriteablePropertyDescriptor>();
            var evaluatorsList         = new List <ExprEvaluator>();
            var widenersList           = new List <TypeWidener>();

            // loop over all columns selected, if any
            for (var i = 0; i < columnNames.Length; i++)
            {
                WriteablePropertyDescriptor selectedWritable = null;
                TypeWidener widener   = null;
                var         evaluator = expressionNodes[i];

                foreach (var desc in writables)
                {
                    if (!desc.PropertyName.Equals(columnNames[i]))
                    {
                        continue;
                    }

                    var columnType = expressionReturnTypes[i];
                    if (columnType == null)
                    {
                        TypeWidenerFactory.GetCheckPropertyAssignType(
                            columnNames[i], null, desc.PropertyType, desc.PropertyName, false, typeWidenerCustomizer,
                            statementName, typeService.EngineURIQualifier);
                    }
                    else if (columnType is EventType)
                    {
                        var columnEventType = (EventType)columnType;
                        var returnType      = columnEventType.UnderlyingType;
                        widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                            columnNames[i], columnEventType.UnderlyingType, desc.PropertyType, desc.PropertyName, false,
                            typeWidenerCustomizer, statementName, typeService.EngineURIQualifier);

                        // handle evaluator returning an event
                        if (TypeHelper.IsSubclassOrImplementsInterface(returnType, desc.PropertyType))
                        {
                            selectedWritable = desc;
                            widener          = input =>
                            {
                                var eventBean = input as EventBean;
                                if (eventBean != null)
                                {
                                    return(eventBean.Underlying);
                                }
                                return(input);
                            };
                            continue;
                        }

                        // find stream
                        var streamNum = 0;
                        for (var j = 0; j < typeService.EventTypes.Length; j++)
                        {
                            if (Equals(typeService.EventTypes[j], columnEventType))
                            {
                                streamNum = j;
                                break;
                            }
                        }
                        var streamNumEval = streamNum;
                        evaluator = new ProxyExprEvaluator
                        {
                            ProcEvaluate = evaluateParams =>
                            {
                                EventBean theEvent = evaluateParams.EventsPerStream[streamNumEval];
                                if (theEvent != null)
                                {
                                    return(theEvent.Underlying);
                                }
                                return(null);
                            },

                            ProcReturnType = () => returnType
                        };
                    }
                    else if (columnType is EventType[])
                    {
                        // handle case where the select-clause contains an fragment array
                        var columnEventType     = ((EventType[])columnType)[0];
                        var componentReturnType = columnEventType.UnderlyingType;
                        var arrayReturnType     = Array.CreateInstance(componentReturnType, 0).GetType();

                        var allowObjectArrayToCollectionConversion = eventType is AvroSchemaEventType;
                        widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                            columnNames[i], arrayReturnType, desc.PropertyType, desc.PropertyName,
                            allowObjectArrayToCollectionConversion, typeWidenerCustomizer, statementName,
                            typeService.EngineURIQualifier);
                        var inner = evaluator;
                        evaluator = new ProxyExprEvaluator
                        {
                            ProcEvaluate = evaluateParams =>
                            {
                                var result = inner.Evaluate(evaluateParams);
                                if (!(result is EventBean[]))
                                {
                                    return(null);
                                }
                                var events = (EventBean[])result;
                                var values = Array.CreateInstance(componentReturnType, events.Length);
                                for (var ii = 0; ii < events.Length; ii++)
                                {
                                    values.SetValue(events[ii].Underlying, ii);
                                }
                                return(values);
                            },

                            ProcReturnType = () => componentReturnType
                        };
                    }
                    else if (!(columnType is Type))
                    {
                        var message = "Invalid assignment of column '" + columnNames[i] +
                                      "' of type '" + columnType +
                                      "' to event property '" + desc.PropertyName +
                                      "' typed as '" + desc.PropertyType.FullName +
                                      "', column and parameter types mismatch";
                        throw new ExprValidationException(message);
                    }
                    else
                    {
                        widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                            columnNames[i], (Type)columnType, desc.PropertyType, desc.PropertyName, false,
                            typeWidenerCustomizer, statementName, typeService.EngineURIQualifier);
                    }

                    selectedWritable = desc;
                    break;
                }

                if (selectedWritable == null)
                {
                    var message = "Column '" + columnNames[i] +
                                  "' could not be assigned to any of the properties of the underlying type (missing column names, event property, setter method or constructor?)";
                    throw new ExprValidationException(message);
                }

                // add
                writablePropertiesList.Add(selectedWritable);
                evaluatorsList.Add(evaluator);
                widenersList.Add(widener);
            }

            // handle wildcard
            if (isUsingWildcard)
            {
                var sourceType = typeService.EventTypes[0];
                foreach (var eventPropDescriptor in sourceType.PropertyDescriptors)
                {
                    if (eventPropDescriptor.RequiresIndex || (eventPropDescriptor.RequiresMapKey))
                    {
                        continue;
                    }

                    WriteablePropertyDescriptor selectedWritable = null;
                    TypeWidener   widener   = null;
                    ExprEvaluator evaluator = null;

                    foreach (var writableDesc in writables)
                    {
                        if (!writableDesc.PropertyName.Equals(eventPropDescriptor.PropertyName))
                        {
                            continue;
                        }

                        widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                            eventPropDescriptor.PropertyName, eventPropDescriptor.PropertyType, writableDesc.PropertyType,
                            writableDesc.PropertyName, false, typeWidenerCustomizer, statementName,
                            typeService.EngineURIQualifier);
                        selectedWritable = writableDesc;

                        var propertyName = eventPropDescriptor.PropertyName;
                        var propertyType = eventPropDescriptor.PropertyType;
                        evaluator = new ProxyExprEvaluator
                        {
                            ProcEvaluate = evaluateParams =>
                            {
                                EventBean theEvent = evaluateParams.EventsPerStream[0];
                                if (theEvent != null)
                                {
                                    return(theEvent.Get(propertyName));
                                }
                                return(null);
                            },

                            ProcReturnType = () => propertyType
                        };
                        break;
                    }

                    if (selectedWritable == null)
                    {
                        var message = "Event property '" + eventPropDescriptor.PropertyName +
                                      "' could not be assigned to any of the properties of the underlying type (missing column names, event property, setter method or constructor?)";
                        throw new ExprValidationException(message);
                    }

                    writablePropertiesList.Add(selectedWritable);
                    evaluatorsList.Add(evaluator);
                    widenersList.Add(widener);
                }
            }

            // assign
            var writableProperties = writablePropertiesList.ToArray();
            var exprEvaluators     = evaluatorsList.ToArray();
            var wideners           = widenersList.ToArray();

            EventBeanManufacturer eventManufacturer;

            try
            {
                eventManufacturer = eventAdapterService.GetManufacturer(
                    eventType, writableProperties, engineImportService, false);
            }
            catch (EventBeanManufactureException e)
            {
                throw new ExprValidationException(e.Message, e);
            }

            return(new SelectExprInsertNativeWidening(eventType, eventManufacturer, exprEvaluators, wideners));
        }
Пример #9
0
        public DataFlowOpInitializeResult Initialize(DataFlowOpInitializateContext context)
        {
            _initialDelayMSec = (long)(initialDelay * 1000);
            _periodDelayMSec  = (long)(interval * 1000);

            if (context.OutputPorts.Count != 1)
            {
                throw new ArgumentException(
                          "BeaconSource operator requires one output stream but produces " + context.OutputPorts.Count +
                          " streams");
            }

            // Check if a type is declared
            var port = context.OutputPorts[0];
            ICollection <string> props;

            if (port.OptionalDeclaredType != null && port.OptionalDeclaredType.EventType != null)
            {
                var outputEventType = port.OptionalDeclaredType.EventType;
                _produceEventBean = port.OptionalDeclaredType != null && !port.OptionalDeclaredType.IsUnderlying;

                // compile properties to populate
                props = _allProperties.Keys;
                props.RemoveAll(PARAMETER_PROPERTIES);
                var writables = SetupProperties(props.ToArray(), outputEventType, context.StatementContext);
                _manufacturer = context.ServicesContext.EventAdapterService.GetManufacturer(
                    outputEventType, writables, context.ServicesContext.EngineImportService, false);

                var index = 0;
                _evaluators = new ExprEvaluator[writables.Length];
                TypeWidenerCustomizer typeWidenerCustomizer =
                    context.ServicesContext.EventAdapterService.GetTypeWidenerCustomizer(outputEventType);
                foreach (var writeable in writables)
                {
                    var providedProperty = _allProperties.Get(writeable.PropertyName);
                    if (providedProperty is ExprNode)
                    {
                        var exprNode  = (ExprNode)providedProperty;
                        var validated = ExprNodeUtility.ValidateSimpleGetSubtree(
                            ExprNodeOrigin.DATAFLOWBEACON, exprNode, context.StatementContext, null, false);
                        var exprEvaluator = validated.ExprEvaluator;
                        var widener       = TypeWidenerFactory.GetCheckPropertyAssignType(
                            ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(validated), exprEvaluator.ReturnType,
                            writeable.PropertyType, writeable.PropertyName, false, typeWidenerCustomizer,
                            context.StatementContext.StatementName, context.Engine.URI);
                        if (widener != null)
                        {
                            _evaluators[index] = new ProxyExprEvaluator
                            {
                                ProcEvaluate = evaluateParams =>
                                {
                                    var value = exprEvaluator.Evaluate(evaluateParams);
                                    return(widener.Invoke(value));
                                },
                                ProcReturnType = () => null
                            };
                        }
                        else
                        {
                            _evaluators[index] = exprEvaluator;
                        }
                    }
                    else if (providedProperty == null)
                    {
                        _evaluators[index] = new ProxyExprEvaluator
                        {
                            ProcEvaluate   = evaluateParams => null,
                            ProcReturnType = () => null
                        };
                    }
                    else
                    {
                        _evaluators[index] = new ProxyExprEvaluator
                        {
                            ProcEvaluate   = evaluateParams => providedProperty,
                            ProcReturnType = () => providedProperty.GetType()
                        };
                    }
                    index++;
                }

                return(null); // no changing types
            }

            // No type has been declared, we can create one
            var anonymousTypeName = context.DataflowName + "-beacon";
            var types             = new LinkedHashMap <string, Object>();

            props = _allProperties.Keys;
            props.RemoveAll(PARAMETER_PROPERTIES);

            var count = 0;

            _evaluators = new ExprEvaluator[props.Count];
            foreach (var propertyName in props)
            {
                var exprNode        = (ExprNode)_allProperties.Get(propertyName);
                var validated       = ExprNodeUtility.ValidateSimpleGetSubtree(ExprNodeOrigin.DATAFLOWBEACON, exprNode, context.StatementContext, null, false);
                var evaluateParamsX = new EvaluateParams(null, true, context.AgentInstanceContext);
                var value           = validated.ExprEvaluator.Evaluate(evaluateParamsX);
                if (value == null)
                {
                    types.Put(propertyName, null);
                }
                else
                {
                    types.Put(propertyName, value.GetType());
                }
                _evaluators[count] = new ProxyExprEvaluator()
                {
                    ProcEvaluate   = (evaluateParams) => value,
                    ProcReturnType = () => null
                };
                count++;
            }

            EventType type =
                context.ServicesContext.EventAdapterService.CreateAnonymousObjectArrayType(anonymousTypeName, types);

            return(new DataFlowOpInitializeResult(
                       new GraphTypeDesc[]
            {
                new GraphTypeDesc(false, true, type)
            }));
        }
Пример #10
0
        public static SelectExprProcessorForge Make(
            EventType[] eventTypes,
            SelectExprForgeContext selectExprForgeContext,
            int streamNumber,
            AvroSchemaEventType targetType,
            ExprNode[] exprNodes,
            string statementName)
        {
            AvroEventType resultType = (AvroEventType) targetType;
            AvroEventType streamType = (AvroEventType) eventTypes[streamNumber];

            // (A) fully assignment-compatible: same number, name and type of fields, no additional expressions: Straight repackage
            if (resultType.Schema.Equals(streamType.Schema) && selectExprForgeContext.ExprForges.Length == 0) {
                return new AvroInsertProcessorSimpleRepackage(selectExprForgeContext, streamNumber, targetType);
            }

            // (B) not completely assignable: find matching properties
            var writables = EventTypeUtility.GetWriteableProperties(resultType, true, false);
            IList<Item> items = new List<Item>();
            IList<WriteablePropertyDescriptor> written = new List<WriteablePropertyDescriptor>();

            // find the properties coming from the providing source stream
            foreach (var writeable in writables) {
                var propertyName = writeable.PropertyName;

                Field streamTypeField = streamType.SchemaAvro.GetField(propertyName);
                Field resultTypeField = resultType.SchemaAvro.GetField(propertyName);

                if (streamTypeField != null && resultTypeField != null) {
                    if (streamTypeField.Schema.Equals(resultTypeField.Schema)) {
                        items.Add(new Item(resultTypeField, streamTypeField, null, null));
                    }
                    else {
                        throw new ExprValidationException(
                            "Type by name '" +
                            resultType.Name +
                            "' " +
                            "in property '" +
                            propertyName +
                            "' expected schema '" +
                            resultTypeField.Schema +
                            "' but received schema '" +
                            streamTypeField.Schema +
                            "'");
                    }
                }
            }

            // find the properties coming from the expressions of the select clause
            var typeWidenerCustomizer =
                selectExprForgeContext.EventTypeAvroHandler.GetTypeWidenerCustomizer(targetType);
            for (var i = 0; i < selectExprForgeContext.ExprForges.Length; i++) {
                var columnName = selectExprForgeContext.ColumnNames[i];
                var exprNode = exprNodes[i];

                var writable = FindWritable(columnName, writables);
                if (writable == null) {
                    throw new ExprValidationException(
                        "Failed to find column '" + columnName + "' in target type '" + resultType.Name + "'");
                }

                Field resultTypeField = resultType.SchemaAvro.GetField(writable.PropertyName);

                TypeWidenerSPI widener;
                try {
                    widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(exprNode),
                        exprNode.Forge.EvaluationType,
                        writable.PropertyType,
                        columnName,
                        false,
                        typeWidenerCustomizer,
                        statementName);
                }
                catch (TypeWidenerException ex) {
                    throw new ExprValidationException(ex.Message, ex);
                }

                items.Add(new Item(resultTypeField, null, exprNode.Forge, widener));
                written.Add(writable);
            }

            // make manufacturer
            Item[] itemsArr = items.ToArray();
            return new AvroInsertProcessorAllocate(
                streamNumber,
                itemsArr,
                resultType,
                resultType.SchemaAvro,
                selectExprForgeContext.EventBeanTypedEventFactory);
        }
Пример #11
0
        public static SelectExprProcessor Make(EventType[] eventTypes, SelectExprContext selectExprContext, int streamNumber, EventType targetType, ExprNode[] exprNodes, EngineImportService engineImportService)
        {
            var mapResultType = (MapEventType)targetType;
            var mapStreamType = (MapEventType)eventTypes[streamNumber];

            // (A) fully assignment-compatible: same number, name and type of fields, no additional expressions: Straight repackage
            String typeSameMssage = BaseNestableEventType.IsDeepEqualsProperties(mapResultType.Name, mapResultType.Types, mapStreamType.Types);

            if (typeSameMssage == null && selectExprContext.ExpressionNodes.Length == 0)
            {
                return(new MapInsertProcessorSimpleRepackage(selectExprContext, streamNumber, targetType));
            }

            // (B) not completely assignable: find matching properties
            ICollection <WriteablePropertyDescriptor> writables = selectExprContext.EventAdapterService.GetWriteableProperties(mapResultType, true);
            IList <Item> items = new List <Item>();
            IList <WriteablePropertyDescriptor> written = new List <WriteablePropertyDescriptor>();

            // find the properties coming from the providing source stream
            int count = 0;

            foreach (WriteablePropertyDescriptor writeable in writables)
            {
                String propertyName = writeable.PropertyName;

                if (mapStreamType.Types.ContainsKey(propertyName))
                {
                    Object setOneType      = mapStreamType.Types.Get(propertyName);
                    Object setTwoType      = mapResultType.Types.Get(propertyName);
                    bool   setTwoTypeFound = mapResultType.Types.ContainsKey(propertyName);
                    String message         = BaseNestableEventUtil.ComparePropType(propertyName, setOneType, setTwoType, setTwoTypeFound, mapResultType.Name);
                    if (message != null)
                    {
                        throw new ExprValidationException(message);
                    }
                    items.Add(new Item(count, propertyName, null, null));
                    written.Add(writeable);
                    count++;
                }
            }

            // find the properties coming from the expressions of the select clause
            for (int i = 0; i < selectExprContext.ExpressionNodes.Length; i++)
            {
                String        columnName = selectExprContext.ColumnNames[i];
                ExprEvaluator evaluator  = selectExprContext.ExpressionNodes[i];
                ExprNode      exprNode   = exprNodes[i];

                WriteablePropertyDescriptor writable = FindWritable(columnName, writables);
                if (writable == null)
                {
                    throw new ExprValidationException("Failed to find column '" + columnName + "' in target type '" + mapResultType.Name + "'");
                }

                TypeWidener widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                    ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(exprNode),
                    exprNode.ExprEvaluator.ReturnType,
                    writable.PropertyType, columnName);
                items.Add(new Item(count, null, evaluator, widener));
                written.Add(writable);
                count++;
            }

            // make manufacturer
            Item[] itemsArr = items.ToArray();
            EventBeanManufacturer manufacturer;

            try {
                manufacturer = selectExprContext.EventAdapterService.GetManufacturer(mapResultType,
                                                                                     written.ToArray(), engineImportService, true);
            }
            catch (EventBeanManufactureException e) {
                throw new ExprValidationException("Failed to write to type: " + e.Message, e);
            }

            return(new MapInsertProcessorAllocate(streamNumber, itemsArr, manufacturer, targetType));
        }
Пример #12
0
        public static EventBeanUpdateHelper Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite)
        {
            IList <EventBeanUpdateItem> updateItems = new List <EventBeanUpdateItem>();
            IList <string> properties = new List <string>();

            for (var i = 0; i < assignments.Count; i++)
            {
                var assignment = assignments[i];
                EventBeanUpdateItem updateItem;

                // determine whether this is a "property=value" assignment, we use property setters in this case
                var possibleAssignment = ExprNodeUtility.CheckGetAssignmentToProp(assignment.Expression);

                // handle assignment "property = value"
                if (possibleAssignment != null)
                {
                    var propertyName     = possibleAssignment.First;
                    var writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                    // check assignment to indexed or mapped property
                    if (writableProperty == null)
                    {
                        var nameWriteablePair = CheckIndexedOrMappedProp(possibleAssignment.First, updatedWindowOrTableName, updatedAlias, eventTypeSPI);
                        propertyName     = nameWriteablePair.First;
                        writableProperty = nameWriteablePair.Second;
                    }

                    var evaluator        = possibleAssignment.Second.ExprEvaluator;
                    var writers          = eventTypeSPI.GetWriter(propertyName);
                    var notNullableField = writableProperty.PropertyType.IsPrimitive;

                    properties.Add(propertyName);
                    var widener = TypeWidenerFactory.GetCheckPropertyAssignType(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(possibleAssignment.Second), possibleAssignment.Second.ExprEvaluator.ReturnType,
                                                                                writableProperty.PropertyType, propertyName);

                    // check event type assignment
                    if (optionalTriggeringEventType != null && possibleAssignment.Second is ExprIdentNode)
                    {
                        var node        = (ExprIdentNode)possibleAssignment.Second;
                        var fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                        var fragmentLHS = eventTypeSPI.GetFragmentType(possibleAssignment.First);
                        if (fragmentRHS != null && fragmentLHS != null && !EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                        {
                            throw new ExprValidationException("Invalid assignment to property '" +
                                                              possibleAssignment.First + "' event type '" + fragmentLHS.FragmentType.Name +
                                                              "' from event type '" + fragmentRHS.FragmentType.Name + "'");
                        }
                    }

                    updateItem = new EventBeanUpdateItem(evaluator, propertyName, writers, notNullableField, widener);
                }
                // handle non-assignment, i.e. UDF or other expression
                else
                {
                    var evaluator = assignment.Expression.ExprEvaluator;
                    updateItem = new EventBeanUpdateItem(evaluator, null, null, false, null);
                }

                updateItems.Add(updateItem);
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethod copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                IList <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                var            propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethod(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                var propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    var propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethod(propertiesInitialValueArray);
                }
            }

            var updateItemsArray = updateItems.ToArray();

            return(new EventBeanUpdateHelper(copyMethod, updateItemsArray));
        }
Пример #13
0
        public static InternalEventRouterDescForge GetValidatePreprocessing(
            EventType eventType,
            UpdateDesc desc,
            Attribute[] annotations)
        {
            if (!(eventType is EventTypeSPI)) {
                throw new ExprValidationException(
                    "Update statements require the event type to implement the " + typeof(EventTypeSPI) + " interface");
            }

            var eventTypeSPI = (EventTypeSPI) eventType;

            var size = desc.Assignments.Count;
            var wideners = new TypeWidenerSPI[size];
            var properties = new string[size];
            var expressions = new ExprNode[size];
            for (var i = 0; i < size; i++) {
                var onSet = desc.Assignments[i];
                var assignmentPair = ExprNodeUtilityValidate.CheckGetAssignmentToProp(onSet.Expression);
                if (assignmentPair == null) {
                    throw new ExprValidationException(
                        "Missing property assignment expression in assignment number " + i);
                }

                properties[i] = assignmentPair.First;
                expressions[i] = assignmentPair.Second;
                var writableProperty = eventTypeSPI.GetWritableProperty(assignmentPair.First);

                if (writableProperty == null) {
                    throw new ExprValidationException(
                        "Property '" + assignmentPair.First + "' is not available for write access");
                }

                try {
                    wideners[i] = TypeWidenerFactory.GetCheckPropertyAssignType(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignmentPair.Second),
                        assignmentPair.Second.Forge.EvaluationType,
                        writableProperty.PropertyType,
                        assignmentPair.First,
                        false,
                        null,
                        null);
                }
                catch (TypeWidenerException ex) {
                    throw new ExprValidationException(ex.Message, ex);
                }
            }

            // check copy-able
            var copyMethod = eventTypeSPI.GetCopyMethodForge(properties);
            if (copyMethod == null) {
                throw new ExprValidationException(
                    "The update-clause requires the underlying event representation to support copy (via Serializable by default)");
            }

            return new InternalEventRouterDescForge(
                copyMethod,
                wideners,
                eventType,
                annotations,
                desc.OptionalWhereClause,
                properties,
                expressions);
        }
        private static SelectExprProcessorForge InitializeJoinWildcardInternal(
            EventType eventType,
            ISet<WriteablePropertyDescriptor> writables,
            string[] streamNames,
            EventType[] streamTypes,
            string statementName,
            ImportServiceCompileTime importService,
            EventTypeAvroHandler eventTypeAvroHandler)
        {
            var typeWidenerCustomizer = eventTypeAvroHandler.GetTypeWidenerCustomizer(eventType);
            IList<WriteablePropertyDescriptor> writablePropertiesList = new List<WriteablePropertyDescriptor>();
            IList<ExprForge> forgesList = new List<ExprForge>();
            IList<TypeWidenerSPI> widenersList = new List<TypeWidenerSPI>();

            // loop over all columns selected, if any
            for (var i = 0; i < streamNames.Length; i++) {
                WriteablePropertyDescriptor selectedWritable = null;
                TypeWidenerSPI widener = null;

                foreach (var desc in writables) {
                    if (!desc.PropertyName.Equals(streamNames[i])) {
                        continue;
                    }

                    try {
                        widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                            streamNames[i],
                            streamTypes[i].UnderlyingType,
                            desc.PropertyType,
                            desc.PropertyName,
                            false,
                            typeWidenerCustomizer,
                            statementName);
                    }
                    catch (TypeWidenerException ex) {
                        throw new ExprValidationException(ex.Message, ex);
                    }

                    selectedWritable = desc;
                    break;
                }

                if (selectedWritable == null) {
                    var message = "Stream underlying object for stream '" +
                                  streamNames[i] +
                                  "' could not be assigned to any of the properties of the underlying type (missing column names, event property or setter method?)";
                    throw new ExprValidationException(message);
                }

                ExprForge forge = new ExprForgeStreamUnderlying(i, streamTypes[i].UnderlyingType);

                // add
                writablePropertiesList.Add(selectedWritable);
                forgesList.Add(forge);
                widenersList.Add(widener);
            }

            // assign
            var writableProperties = writablePropertiesList.ToArray();
            var exprForges = forgesList.ToArray();
            var wideners = widenersList.ToArray();

            EventBeanManufacturerForge eventManufacturer;
            try {
                eventManufacturer = EventTypeUtility.GetManufacturer(
                    eventType,
                    writableProperties,
                    importService,
                    false,
                    eventTypeAvroHandler);
            }
            catch (EventBeanManufactureException e) {
                throw new ExprValidationException(e.Message, e);
            }

            return new SelectExprInsertNativeWidening(eventType, eventManufacturer, exprForges, wideners);
        }
        private static SelectExprProcessorForge InitializeSetterManufactor(
            EventType eventType,
            ISet<WriteablePropertyDescriptor> writables,
            bool isUsingWildcard,
            StreamTypeService typeService,
            ExprForge[] expressionForges,
            string[] columnNames,
            object[] expressionReturnTypes,
            string statementName,
            ImportServiceCompileTime importService,
            EventTypeAvroHandler eventTypeAvroHandler)
        {
            var typeWidenerCustomizer = eventTypeAvroHandler.GetTypeWidenerCustomizer(eventType);
            IList<WriteablePropertyDescriptor> writablePropertiesList = new List<WriteablePropertyDescriptor>();
            IList<ExprForge> forgesList = new List<ExprForge>();
            IList<TypeWidenerSPI> widenersList = new List<TypeWidenerSPI>();

            // loop over all columns selected, if any
            for (var i = 0; i < columnNames.Length; i++) {
                WriteablePropertyDescriptor selectedWritable = null;
                TypeWidenerSPI widener = null;
                var forge = expressionForges[i];

                foreach (var desc in writables) {
                    if (!desc.PropertyName.Equals(columnNames[i])) {
                        continue;
                    }

                    var columnType = expressionReturnTypes[i];
                    if (columnType == null) {
                        try {
                            TypeWidenerFactory.GetCheckPropertyAssignType(
                                columnNames[i],
                                null,
                                desc.PropertyType,
                                desc.PropertyName,
                                false,
                                typeWidenerCustomizer,
                                statementName);
                        }
                        catch (TypeWidenerException ex) {
                            throw new ExprValidationException(ex.Message, ex);
                        }
                    }
                    else if (columnType is EventType) {
                        var columnEventType = (EventType) columnType;
                        var returnType = columnEventType.UnderlyingType;
                        try {
                            widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                columnNames[i],
                                columnEventType.UnderlyingType,
                                desc.PropertyType,
                                desc.PropertyName,
                                false,
                                typeWidenerCustomizer,
                                statementName);
                        }
                        catch (TypeWidenerException ex) {
                            throw new ExprValidationException(ex.Message, ex);
                        }

                        // handle evaluator returning an event
                        if (TypeHelper.IsSubclassOrImplementsInterface(returnType, desc.PropertyType)) {
                            selectedWritable = desc;
                            widener = new ProxyTypeWidenerSPI {
                                ProcWidenResultType = () => desc.PropertyType,
                                ProcWiden = input => {
                                    if (input is EventBean eventBean) {
                                        return eventBean.Underlying;
                                    }

                                    return input;
                                },

                                ProcWidenCodegen = (
                                    expression,
                                    codegenMethodScope,
                                    codegenClassScope) => {
                                    var method = codegenMethodScope
                                        .MakeChild(typeof(object), typeof(TypeWidenerSPI), codegenClassScope)
                                        .AddParam(typeof(object), "input")
                                        .Block
                                        .IfCondition(InstanceOf(Ref("input"), typeof(EventBean)))
                                        .BlockReturn(
                                            ExprDotName(Cast(typeof(EventBean), Ref("input")), "Underlying"))
                                        .MethodReturn(Ref("input"));
                                    return LocalMethodBuild(method).Pass(expression).Call();
                                }
                            };
                            continue;
                        }

                        // find stream
                        var streamNum = 0;
                        for (var j = 0; j < typeService.EventTypes.Length; j++) {
                            if (typeService.EventTypes[j] == columnEventType) {
                                streamNum = j;
                                break;
                            }
                        }

                        forge = new ExprForgeStreamUnderlying(
                            streamNum,
                            typeService.EventTypes[streamNum].UnderlyingType);
                    }
                    else if (columnType is EventType[]) {
                        // handle case where the select-clause contains an fragment array
                        var columnEventType = ((EventType[]) columnType)[0];
                        var componentReturnType = columnEventType.UnderlyingType;
                        var arrayReturnType = componentReturnType.MakeArrayType();

                        var allowObjectArrayToCollectionConversion = eventType is AvroSchemaEventType;
                        try {
                            widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                columnNames[i],
                                arrayReturnType,
                                desc.PropertyType,
                                desc.PropertyName,
                                allowObjectArrayToCollectionConversion,
                                typeWidenerCustomizer,
                                statementName);
                        }
                        catch (TypeWidenerException ex) {
                            throw new ExprValidationException(ex.Message, ex);
                        }

                        var inner = forge;
                        forge = new ExprForgeStreamWithInner(inner, componentReturnType);
                    }
                    else if (!(columnType is Type columnAsType)) {
                        var message = "Invalid assignment of column '" +
                                      columnNames[i] +
                                      "' of type '" +
                                      columnType +
                                      "' to event property '" +
                                      desc.PropertyName +
                                      "' typed as '" +
                                      desc.PropertyType.CleanName() +
                                      "', column and parameter types mismatch";
                        throw new ExprValidationException(message);
                    }
                    else {
                        try {
                            widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                columnNames[i],
                                (Type) columnType,
                                desc.PropertyType,
                                desc.PropertyName,
                                false,
                                typeWidenerCustomizer,
                                statementName);
                        }
                        catch (TypeWidenerException ex) {
                            throw new ExprValidationException(ex.Message, ex);
                        }
                    }

                    selectedWritable = desc;
                    break;
                }

                if (selectedWritable == null) {
                    var message = "Column '" +
                                  columnNames[i] +
                                  "' could not be assigned to any of the properties of the underlying type (missing column names, event property, setter method or constructor?)";
                    throw new ExprValidationException(message);
                }

                // add
                writablePropertiesList.Add(selectedWritable);
                forgesList.Add(forge);
                widenersList.Add(widener);
            }

            // handle wildcard
            if (isUsingWildcard) {
                var sourceType = typeService.EventTypes[0];
                foreach (var eventPropDescriptor in sourceType.PropertyDescriptors) {
                    if (eventPropDescriptor.IsRequiresIndex || eventPropDescriptor.IsRequiresMapKey) {
                        continue;
                    }

                    WriteablePropertyDescriptor selectedWritable = null;
                    TypeWidenerSPI widener = null;
                    ExprForge forge = null;

                    foreach (var writableDesc in writables) {
                        if (!writableDesc.PropertyName.Equals(eventPropDescriptor.PropertyName)) {
                            continue;
                        }

                        try {
                            widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                eventPropDescriptor.PropertyName,
                                eventPropDescriptor.PropertyType,
                                writableDesc.PropertyType,
                                writableDesc.PropertyName,
                                false,
                                typeWidenerCustomizer,
                                statementName);
                        }
                        catch (TypeWidenerException ex) {
                            throw new ExprValidationException(ex.Message, ex);
                        }

                        selectedWritable = writableDesc;

                        var propertyName = eventPropDescriptor.PropertyName;
                        var getter = ((EventTypeSPI) sourceType).GetGetterSPI(propertyName);
                        forge = new ExprForgeStreamWithGetter(getter);
                        break;
                    }

                    if (selectedWritable == null) {
                        var message = "Event property '" +
                                      eventPropDescriptor.PropertyName +
                                      "' could not be assigned to any of the properties of the underlying type (missing column names, event property, setter method or constructor?)";
                        throw new ExprValidationException(message);
                    }

                    writablePropertiesList.Add(selectedWritable);
                    forgesList.Add(forge);
                    widenersList.Add(widener);
                }
            }

            // assign
            var writableProperties = writablePropertiesList.ToArray();
            var exprForges = forgesList.ToArray();
            var wideners = widenersList.ToArray();

            EventBeanManufacturerForge eventManufacturer;
            try {
                eventManufacturer = EventTypeUtility.GetManufacturer(
                    eventType,
                    writableProperties,
                    importService,
                    false,
                    eventTypeAvroHandler);
            }
            catch (EventBeanManufactureException e) {
                throw new ExprValidationException(e.Message, e);
            }
            
            if (eventManufacturer == null) {
                return null;
            }

            return new SelectExprInsertNativeWidening(eventType, eventManufacturer, exprForges, wideners);
        }
Пример #16
0
        private DataFlowOpForgeInitializeResult InitializeTypeDeclared(
            DataFlowOpOutputPort port,
            DataFlowOpForgeInitializeContext context)
        {
            produceEventBean = port.OptionalDeclaredType != null && !port.OptionalDeclaredType.IsUnderlying;

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

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

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

                index++;
            }

            return null;
        }
Пример #17
0
        public EvalSelectNoWildcardAvro(
            SelectExprForgeContext selectExprForgeContext,
            ExprForge[] exprForges,
            EventType resultEventTypeAvro,
            string statementName)
        {
            _selectExprForgeContext = selectExprForgeContext;
            _resultEventTypeAvro = (AvroEventType) resultEventTypeAvro;

            _forges = new ExprForge[selectExprForgeContext.ExprForges.Length];
            var typeWidenerCustomizer =
                selectExprForgeContext.EventTypeAvroHandler.GetTypeWidenerCustomizer(resultEventTypeAvro);
            for (var i = 0; i < _forges.Length; i++) {
                _forges[i] = selectExprForgeContext.ExprForges[i];
                var forge = exprForges[i];
                var forgeEvaluationType = forge.EvaluationType;

                if (forge is ExprEvalByGetterFragment) {
                    _forges[i] = HandleFragment((ExprEvalByGetterFragment) forge);
                }
                else if (forge is ExprEvalStreamInsertBean) {
                    var und = (ExprEvalStreamInsertBean) forge;
                    _forges[i] =
                        new SelectExprInsertEventBeanFactory.ExprForgeStreamUnderlying(und.StreamNum, typeof(object));
                }
                else if (forge is SelectExprProcessorTypableMapForge) {
                    var typableMap = (SelectExprProcessorTypableMapForge) forge;
                    _forges[i] = new SelectExprProcessorEvalAvroMapToAvro(
                        typableMap.InnerForge,
                        ((AvroEventType) resultEventTypeAvro).SchemaAvro,
                        selectExprForgeContext.ColumnNames[i]);
                }
                else if (forge is ExprEvalStreamInsertNamedWindow) {
                    var nw = (ExprEvalStreamInsertNamedWindow) forge;
                    _forges[i] =
                        new SelectExprInsertEventBeanFactory.ExprForgeStreamUnderlying(nw.StreamNum, typeof(object));
                }
                else if (forgeEvaluationType != null && forgeEvaluationType.IsArray) {
                    var widener = TypeWidenerFactory.GetArrayToCollectionCoercer(forgeEvaluationType.GetElementType());
                    var resultType = typeof(ICollection<object>);
                    _forges[i] = new SelectExprProcessorEvalAvroArrayCoercer(forge, widener, resultType);
                }
                else {
                    var propertyName = selectExprForgeContext.ColumnNames[i];
                    var propertyType = resultEventTypeAvro.GetPropertyType(propertyName);
                    TypeWidenerSPI widener;
                    try {
                        widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                            propertyName,
                            forgeEvaluationType,
                            propertyType,
                            propertyName,
                            true,
                            typeWidenerCustomizer,
                            statementName);
                    }
                    catch (TypeWidenerException ex) {
                        throw new ExprValidationException(ex.Message, ex);
                    }

                    if (widener != null) {
                        _forges[i] = new SelectExprProcessorEvalAvroArrayCoercer(forge, widener, propertyType);
                    }
                }
            }
        }
        public VariableReadWritePackageForge(
            IList <OnTriggerSetAssignment> assignments,
            string statementName,
            StatementCompileTimeServices services)
        {
            _variables     = new VariableMetaData[assignments.Count];
            _mustCoerce    = new bool[assignments.Count];
            _writers       = new VariableTriggerWriteForge[assignments.Count];
            _variableTypes = new Dictionary <string, object>();

            IDictionary <EventTypeSPI, CopyMethodDesc> eventTypeWrittenProps = new Dictionary <EventTypeSPI, CopyMethodDesc>();
            var count = 0;
            IList <ExprAssignment> assignmentList = new List <ExprAssignment>();

            foreach (var spec in assignments)
            {
                var assignmentDesc = spec.Validated;
                assignmentList.Add(assignmentDesc);

                try {
                    if (assignmentDesc is ExprAssignmentStraight)
                    {
                        var assignment      = (ExprAssignmentStraight)assignmentDesc;
                        var identAssignment = assignment.Lhs;

                        var variableName     = identAssignment.Ident;
                        var variableMetadata = services.VariableCompileTimeResolver.Resolve(variableName);
                        if (variableMetadata == null)
                        {
                            throw new ExprValidationException("Variable by name '" + variableName + "' has not been created or configured");
                        }

                        _variables[count] = variableMetadata;
                        var expressionType = assignment.Rhs.Forge.EvaluationType;

                        if (assignment.Lhs is ExprAssignmentLHSIdent)
                        {
                            // determine types
                            if (variableMetadata.EventType != null)
                            {
                                if ((expressionType != null) &&
                                    (!TypeHelper.IsSubclassOrImplementsInterface(expressionType, variableMetadata.EventType.UnderlyingType)))
                                {
                                    throw new ExprValidationException(
                                              "Variable '" +
                                              variableName +
                                              "' of declared event type '" +
                                              variableMetadata.EventType.Name +
                                              "' underlying type '" +
                                              variableMetadata.EventType.UnderlyingType.Name +
                                              "' cannot be assigned a value of type '" +
                                              expressionType.Name +
                                              "'");
                                }

                                _variableTypes.Put(variableName, variableMetadata.EventType.UnderlyingType);
                            }
                            else
                            {
                                var variableType = variableMetadata.Type;
                                _variableTypes.Put(variableName, variableType);

                                // determine if the expression type can be assigned
                                if (variableType != typeof(object))
                                {
                                    if ((expressionType.GetBoxedType() != variableType.GetBoxedType()) &&
                                        (expressionType != null))
                                    {
                                        if ((!TypeHelper.IsNumeric(variableType)) ||
                                            (!TypeHelper.IsNumeric(expressionType)))
                                        {
                                            throw new ExprValidationException(VariableUtil.GetAssigmentExMessage(variableName, variableType, expressionType));
                                        }

                                        if (!(TypeHelper.CanCoerce(expressionType, variableType)))
                                        {
                                            throw new ExprValidationException(VariableUtil.GetAssigmentExMessage(variableName, variableType, expressionType));
                                        }

                                        _mustCoerce[count] = true;
                                    }
                                }
                            }
                        }
                        else if (assignment.Lhs is ExprAssignmentLHSIdentWSubprop)
                        {
                            var subpropAssignment = (ExprAssignmentLHSIdentWSubprop)assignment.Lhs;
                            var subPropertyName   = subpropAssignment.SubpropertyName;
                            if (variableMetadata.EventType == null)
                            {
                                throw new ExprValidationException(
                                          "Variable by name '" + variableName + "' does not have a property named '" + subPropertyName + "'");
                            }

                            var type = variableMetadata.EventType;
                            if (!(type is EventTypeSPI))
                            {
                                throw new ExprValidationException("Variable by name '" + variableName + "' event type '" + type.Name + "' not writable");
                            }

                            var spi        = (EventTypeSPI)type;
                            var writer     = spi.GetWriter(subPropertyName);
                            var getter     = spi.GetGetterSPI(subPropertyName);
                            var getterType = spi.GetPropertyType(subPropertyName);
                            if (writer == null)
                            {
                                throw new ExprValidationException(
                                          "Variable by name '" + variableName + "' the property '" + subPropertyName + "' is not writable");
                            }

                            var fullVariableName = variableName + "." + subPropertyName;
                            _variableTypes.Put(fullVariableName, spi.GetPropertyType(subPropertyName));
                            var writtenProps = eventTypeWrittenProps.Get(spi);
                            if (writtenProps == null)
                            {
                                writtenProps = new CopyMethodDesc(variableName, new List <string>());
                                eventTypeWrittenProps.Put(spi, writtenProps);
                            }

                            writtenProps.PropertiesCopied.Add(subPropertyName);

                            _writers[count] = new VariableTriggerWriteDescForge(
                                spi,
                                variableName,
                                writer,
                                getter,
                                getterType,
                                assignment.Rhs.Forge.EvaluationType);
                        }
                        else if (assignment.Lhs is ExprAssignmentLHSArrayElement)
                        {
                            var arrayAssign  = (ExprAssignmentLHSArrayElement)assignment.Lhs;
                            var variableType = variableMetadata.Type;
                            if (!variableType.IsArray)
                            {
                                throw new ExprValidationException("Variable '" + variableMetadata.VariableName + "' is not an array");
                            }

                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignment.Rhs),
                                    expressionType,
                                    variableType.GetElementType(),
                                    variableMetadata.VariableName,
                                    false,
                                    null,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            _writers[count] = new VariableTriggerWriteArrayElementForge(variableName, arrayAssign.IndexExpression.Forge, widener);
                        }
                        else
                        {
                            throw new IllegalStateException("Unrecognized left hand side assignment " + assignment.Lhs);
                        }
                    }
                    else if (assignmentDesc is ExprAssignmentCurly)
                    {
                        var curly = (ExprAssignmentCurly)assignmentDesc;
                        if (curly.Expression is ExprVariableNode)
                        {
                            throw new ExprValidationException("Missing variable assignment expression in assignment number " + count);
                        }

                        var variableVisitor = new ExprNodeVariableVisitor(services.VariableCompileTimeResolver);
                        curly.Expression.Accept(variableVisitor);
                        if (variableVisitor.VariableNames == null || variableVisitor.VariableNames.Count != 1)
                        {
                            throw new ExprValidationException("Assignment expression must receive a single variable value");
                        }

                        var variable = variableVisitor.VariableNames.First();
                        _variables[count] = variable.Value;
                        _writers[count]   = new VariableTriggerWriteCurlyForge(variable.Key, curly.Expression.Forge);
                    }
                    else
                    {
                        throw new IllegalStateException("Unrecognized assignment expression " + assignmentDesc);
                    }

                    if (_variables[count].IsConstant)
                    {
                        throw new ExprValidationException("Variable by name '" + _variables[count].VariableName + "' is declared constant and may not be set");
                    }

                    count++;
                }
                catch (ExprValidationException ex) {
                    throw new ExprValidationException(
                              "Failed to validate assignment expression '" +
                              ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignmentDesc.OriginalExpression) +
                              "': " +
                              ex.Message,
                              ex);
                }
            }

            _assignments = assignmentList.ToArray();

            if (eventTypeWrittenProps.IsEmpty())
            {
                _copyMethods = EmptyDictionary <EventTypeSPI, EventBeanCopyMethodForge> .Instance;
                return;
            }

            _copyMethods = new Dictionary <EventTypeSPI, EventBeanCopyMethodForge>();
            foreach (var entry in eventTypeWrittenProps)
            {
                var propsWritten = entry.Value.PropertiesCopied;
                var props        = propsWritten.ToArray();
                var copyMethod   = entry.Key.GetCopyMethodForge(props);
                if (copyMethod == null)
                {
                    throw new ExprValidationException(
                              "Variable '" +
                              entry.Value.VariableName +
                              "' of declared type " +
                              entry.Key.UnderlyingType.CleanName() +
                              "' cannot be assigned to");
                }

                _copyMethods.Put(entry.Key, copyMethod);
            }
        }
        private static SelectExprProcessor InitializeJoinWildcardInternal(
            EventType eventType,
            ICollection <WriteablePropertyDescriptor> writables,
            string[] streamNames,
            EventType[] streamTypes,
            EngineImportService engineImportService,
            EventAdapterService eventAdapterService,
            string statementName,
            string engineURI)
        {
            var typeWidenerCustomizer  = eventAdapterService.GetTypeWidenerCustomizer(eventType);
            var writablePropertiesList = new List <WriteablePropertyDescriptor>();
            var evaluatorsList         = new List <ExprEvaluator>();
            var widenersList           = new List <TypeWidener>();

            // loop over all columns selected, if any
            for (var i = 0; i < streamNames.Length; i++)
            {
                WriteablePropertyDescriptor selectedWritable = null;
                TypeWidener widener = null;

                foreach (var desc in writables)
                {
                    if (!desc.PropertyName.Equals(streamNames[i]))
                    {
                        continue;
                    }

                    widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        streamNames[i], streamTypes[i].UnderlyingType, desc.PropertyType, desc.PropertyName, false,
                        typeWidenerCustomizer, statementName, engineURI);
                    selectedWritable = desc;
                    break;
                }

                if (selectedWritable == null)
                {
                    var message = "Stream underlying object for stream '" + streamNames[i] +
                                  "' could not be assigned to any of the properties of the underlying type (missing column names, event property or setter method?)";
                    throw new ExprValidationException(message);
                }

                var streamNum  = i;
                var returnType = streamTypes[streamNum].UnderlyingType;
                var evaluator  = new ProxyExprEvaluator
                {
                    ProcEvaluate = evaluateParams =>
                    {
                        EventBean theEvent = evaluateParams.EventsPerStream[streamNum];
                        if (theEvent != null)
                        {
                            return(theEvent.Underlying);
                        }
                        return(null);
                    },

                    ProcReturnType = () => returnType
                };

                // add
                writablePropertiesList.Add(selectedWritable);
                evaluatorsList.Add(evaluator);
                widenersList.Add(widener);
            }

            // assign
            var writableProperties = writablePropertiesList.ToArray();
            var exprEvaluators     = evaluatorsList.ToArray();
            var wideners           = widenersList.ToArray();

            EventBeanManufacturer eventManufacturer;

            try
            {
                eventManufacturer = eventAdapterService.GetManufacturer(
                    eventType, writableProperties, engineImportService, false);
            }
            catch (EventBeanManufactureException e)
            {
                throw new ExprValidationException(e.Message, e);
            }

            return(new SelectExprInsertNativeWidening(eventType, eventManufacturer, exprEvaluators, wideners));
        }
        public static EventBeanUpdateHelperForge Make(
            string updatedWindowOrTableName,
            EventTypeSPI eventTypeSPI,
            IList <OnTriggerSetAssignment> assignments,
            string updatedAlias,
            EventType optionalTriggeringEventType,
            bool isCopyOnWrite,
            string statementName,
            EventTypeAvroHandler avroHandler)
        {
            IList <EventBeanUpdateItemForge> updateItems = new List <EventBeanUpdateItemForge>();
            IList <string> properties = new List <string>();

            TypeWidenerCustomizer typeWidenerCustomizer = avroHandler.GetTypeWidenerCustomizer(eventTypeSPI);

            for (int i = 0; i < assignments.Count; i++)
            {
                OnTriggerSetAssignment desc       = assignments[i];
                ExprAssignment         assignment = desc.Validated;
                if (assignment == null)
                {
                    throw new IllegalStateException("Assignment has not been validated");
                }

                try {
                    EventBeanUpdateItemForge updateItem;
                    if (assignment is ExprAssignmentStraight)
                    {
                        ExprAssignmentStraight straight = (ExprAssignmentStraight)assignment;

                        // handle assignment "property = value"
                        if (straight.Lhs is ExprAssignmentLHSIdent)
                        {
                            ExprAssignmentLHSIdent ident = (ExprAssignmentLHSIdent)straight.Lhs;

                            string propertyName = ident.Ident;
                            EventPropertyDescriptor writableProperty = eventTypeSPI.GetWritableProperty(propertyName);

                            // check assignment to indexed or mapped property
                            if (writableProperty == null)
                            {
                                Pair <string, EventPropertyDescriptor> nameWriteablePair = CheckIndexedOrMappedProp(
                                    propertyName,
                                    updatedWindowOrTableName,
                                    updatedAlias,
                                    eventTypeSPI);
                                propertyName     = nameWriteablePair.First;
                                writableProperty = nameWriteablePair.Second;
                            }

                            ExprNode  rhsExpr             = straight.Rhs;
                            ExprForge rhsForge            = rhsExpr.Forge;
                            EventPropertyWriterSPI writer = eventTypeSPI.GetWriter(propertyName);
                            bool notNullableField         = writableProperty.PropertyType.IsPrimitive;

                            properties.Add(propertyName);
                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(rhsExpr),
                                    rhsForge.EvaluationType,
                                    writableProperty.PropertyType,
                                    propertyName,
                                    false,
                                    typeWidenerCustomizer,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            // check event type assignment
                            bool useUntypedAssignment = false;
                            bool useTriggeringEvent   = false;
                            if (optionalTriggeringEventType != null)
                            {
                                // handle RHS is ident node
                                if (rhsExpr is ExprIdentNode)
                                {
                                    ExprIdentNode     node        = (ExprIdentNode)rhsExpr;
                                    FragmentEventType fragmentRHS = optionalTriggeringEventType.GetFragmentType(node.ResolvedPropertyName);
                                    FragmentEventType fragmentLHS = eventTypeSPI.GetFragmentType(propertyName);
                                    if (fragmentRHS != null && fragmentLHS != null)
                                    {
                                        if (!EventTypeUtility.IsTypeOrSubTypeOf(fragmentRHS.FragmentType, fragmentLHS.FragmentType))
                                        {
                                            throw MakeEventTypeMismatch(propertyName, fragmentLHS.FragmentType, fragmentRHS.FragmentType);
                                        }
                                    }

                                    // we don't need to cast if it is a self-assignment and LHS is an event and target needs no writer
                                    if (node.StreamId == 0 && fragmentLHS != null && eventTypeSPI is BaseNestableEventType)
                                    {
                                        useUntypedAssignment = true;
                                    }
                                }

                                // handle RHS is a stream of the triggering event itself
                                if (rhsExpr is ExprStreamUnderlyingNode)
                                {
                                    ExprStreamUnderlyingNode und = (ExprStreamUnderlyingNode)rhsExpr;
                                    if (und.StreamId == 1)
                                    {
                                        FragmentEventType fragmentLHS = eventTypeSPI.GetFragmentType(propertyName);
                                        if (fragmentLHS != null &&
                                            optionalTriggeringEventType is BaseNestableEventType &&
                                            !EventTypeUtility.IsTypeOrSubTypeOf(optionalTriggeringEventType, fragmentLHS.FragmentType))
                                        {
                                            throw MakeEventTypeMismatch(propertyName, fragmentLHS.FragmentType, optionalTriggeringEventType);
                                        }

                                        // we use the event itself for assignment and target needs no writer
                                        if (eventTypeSPI is BaseNestableEventType)
                                        {
                                            useUntypedAssignment = true;
                                            useTriggeringEvent   = true;
                                        }
                                    }
                                }
                            }

                            updateItem = new EventBeanUpdateItemForge(
                                rhsForge,
                                propertyName,
                                writer,
                                notNullableField,
                                widener,
                                useUntypedAssignment,
                                useTriggeringEvent,
                                null);
                        }
                        else if (straight.Lhs is ExprAssignmentLHSArrayElement)
                        {
                            // handle "property[expr] = value"
                            ExprAssignmentLHSArrayElement arrayElementLHS = (ExprAssignmentLHSArrayElement)straight.Lhs;
                            string   arrayPropertyName = arrayElementLHS.Ident;
                            ExprNode rhs            = straight.Rhs;
                            Type     evaluationType = rhs.Forge.EvaluationType;
                            Type     propertyType   = eventTypeSPI.GetPropertyType(arrayPropertyName);
                            if (!eventTypeSPI.IsProperty(arrayPropertyName))
                            {
                                throw new ExprValidationException("Property '" + arrayPropertyName + "' could not be found");
                            }

                            if (propertyType == null || !propertyType.IsArray)
                            {
                                throw new ExprValidationException("Property '" + arrayPropertyName + "' is not an array");
                            }

                            EventPropertyGetterSPI getter = eventTypeSPI.GetGetterSPI(arrayPropertyName);
                            Type componentType            = propertyType.GetElementType();
                            if (!TypeHelper.IsAssignmentCompatible(evaluationType, componentType))
                            {
                                throw new ExprValidationException(
                                          "Invalid assignment to property '" +
                                          arrayPropertyName +
                                          "' component type '" +
                                          componentType.CleanName() +
                                          "' from expression returning '" +
                                          evaluationType.CleanName() +
                                          "'");
                            }

                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(straight.Rhs),
                                    evaluationType,
                                    componentType,
                                    arrayPropertyName,
                                    false,
                                    typeWidenerCustomizer,
                                    statementName);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            EventBeanUpdateItemArray arrayInfo = new EventBeanUpdateItemArray(
                                arrayPropertyName,
                                arrayElementLHS.IndexExpression,
                                propertyType,
                                getter);
                            updateItem = new EventBeanUpdateItemForge(
                                rhs.Forge,
                                arrayPropertyName,
                                null,
                                false,
                                widener,
                                false,
                                false,
                                arrayInfo);
                        }
                        else
                        {
                            throw new IllegalStateException("Unrecognized LHS assignment " + straight);
                        }
                    }
                    else if (assignment is ExprAssignmentCurly)
                    {
                        // handle non-assignment, i.e. UDF or other expression
                        ExprAssignmentCurly dot = (ExprAssignmentCurly)assignment;
                        updateItem = new EventBeanUpdateItemForge(
                            dot.Expression.Forge,
                            null,
                            null,
                            false,
                            null,
                            false,
                            false,
                            null);
                    }
                    else
                    {
                        throw new IllegalStateException("Unrecognized assignment " + assignment);
                    }

                    updateItems.Add(updateItem);
                }
                catch (ExprValidationException ex) {
                    throw new ExprValidationException(
                              "Failed to validate assignment expression '" +
                              ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignment.OriginalExpression) +
                              "': " +
                              ex.Message,
                              ex);
                }
            }

            // copy-on-write is the default event semantics as events are immutable
            EventBeanCopyMethodForge copyMethod;

            if (isCopyOnWrite)
            {
                // obtain copy method
                List <string> propertiesUniqueList = new List <string>(new HashSet <string>(properties));
                string[]      propertiesArray      = propertiesUniqueList.ToArray();
                copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesArray);
                if (copyMethod == null)
                {
                    throw new ExprValidationException("Event type does not support event bean copy");
                }
            }
            else
            {
                // for in-place update, determine assignment expressions to use "initial" to access prior-change values
                // the copy-method is optional
                copyMethod = null;
                ISet <string> propertiesInitialValue = DeterminePropertiesInitialValue(assignments);
                if (!propertiesInitialValue.IsEmpty())
                {
                    string[] propertiesInitialValueArray = propertiesInitialValue.ToArray();
                    copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesInitialValueArray);
                }
            }

            EventBeanUpdateItemForge[] updateItemsArray = updateItems.ToArray();
            return(new EventBeanUpdateHelperForge(eventTypeSPI, copyMethod, updateItemsArray));
        }
        public static SelectExprProcessorForge Make(
            EventType[] eventTypes,
            SelectExprForgeContext selectExprForgeContext,
            int streamNumber,
            EventType targetType,
            ExprNode[] exprNodes,
            ImportServiceCompileTime importService,
            string statementName)
        {
            var oaResultType = (ObjectArrayEventType) targetType;
            var oaStreamType = (ObjectArrayEventType) eventTypes[streamNumber];

            // (A) fully assignment-compatible: same number, name and type of fields, no additional expressions: Straight repackage
            if (oaResultType.IsDeepEqualsConsiderOrder(oaStreamType) && selectExprForgeContext.ExprForges.Length == 0) {
                return new OAInsertProcessorSimpleRepackage(selectExprForgeContext, streamNumber, targetType);
            }

            // (B) not completely assignable: find matching properties
            var writables = EventTypeUtility.GetWriteableProperties(oaResultType, true, false);
            IList<Item> items = new List<Item>();
            IList<WriteablePropertyDescriptor> written = new List<WriteablePropertyDescriptor>();

            // find the properties coming from the providing source stream
            foreach (var writeable in writables) {
                var propertyName = writeable.PropertyName;

                var hasIndexSource = oaStreamType.PropertiesIndexes.TryGetValue(propertyName, out var indexSource);
                var hasIndexTarget = oaResultType.PropertiesIndexes.TryGetValue(propertyName, out var indexTarget);
                if (hasIndexSource) {
                    var setOneType = oaStreamType.Types.Get(propertyName);
                    var setTwoType = oaResultType.Types.Get(propertyName);
                    var setTwoTypeFound = oaResultType.Types.ContainsKey(propertyName);
                    var message = BaseNestableEventUtil.ComparePropType(
                        propertyName,
                        setOneType,
                        setTwoType,
                        setTwoTypeFound,
                        oaResultType.Name);
                    if (message != null) {
                        throw new ExprValidationException(message.Message, message);
                    }

                    items.Add(new Item(indexTarget, indexSource, null, null));
                    written.Add(writeable);
                }
            }

            // find the properties coming from the expressions of the select clause
            var count = written.Count;
            for (var i = 0; i < selectExprForgeContext.ExprForges.Length; i++) {
                var columnName = selectExprForgeContext.ColumnNames[i];
                var forge = selectExprForgeContext.ExprForges[i];
                var exprNode = exprNodes[i];

                var writable = FindWritable(columnName, writables);
                if (writable == null) {
                    throw new ExprValidationException(
                        "Failed to find column '" + columnName + "' in target type '" + oaResultType.Name + "'");
                }

                TypeWidenerSPI widener;
                try {
                    widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(exprNode),
                        exprNode.Forge.EvaluationType,
                        writable.PropertyType,
                        columnName,
                        false,
                        null,
                        statementName);
                }
                catch (TypeWidenerException ex) {
                    throw new ExprValidationException(ex.Message, ex);
                }

                items.Add(new Item(count, -1, forge, widener));
                written.Add(writable);
                count++;
            }

            // make manufacturer
            var itemsArr = items.ToArray();
            EventBeanManufacturerForge manufacturer;
            try {
                manufacturer = EventTypeUtility.GetManufacturer(
                    oaResultType,
                    written.ToArray(),
                    importService,
                    true,
                    selectExprForgeContext.EventTypeAvroHandler);
            }
            catch (EventBeanManufactureException e) {
                throw new ExprValidationException("Failed to write to type: " + e.Message, e);
            }

            return new OAInsertProcessorAllocate(streamNumber, itemsArr, manufacturer, targetType);
        }
Пример #22
0
        public static InternalEventRouterDescForge GetValidatePreprocessing(
            EventType eventType,
            UpdateDesc desc,
            Attribute[] annotations)
        {
            if (!(eventType is EventTypeSPI)) {
                throw new ExprValidationException("Update statements require the event type to implement the " + typeof(EventTypeSPI) + " interface");
            }

            var eventTypeSPI = (EventTypeSPI) eventType;

            var wideners = new List<TypeWidenerSPI>();
            var properties = new List<string>();
            var propertiesTouched = new List<string>();
            var expressions = new List<ExprNode>();
            var specialWriters = new List<InternalEventRouterWriterForge>();

            for (var i = 0; i < desc.Assignments.Count; i++) {
                var onSet = desc.Assignments[i];
                var assignmentDesc = onSet.Validated;

                try {
                    if (assignmentDesc is ExprAssignmentStraight assignment) {
                        var lhs = assignment.Lhs;

                        if (lhs is ExprAssignmentLHSIdent ident) {
                            var propertyName = ident.Ident;
                            var writableProperty = eventTypeSPI.GetWritableProperty(propertyName);
                            if (writableProperty == null) {
                                throw new ExprValidationException("Property '" + propertyName + "' is not available for write access");
                            }

                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignment.Rhs),
                                    assignment.Rhs.Forge.EvaluationType,
                                    writableProperty.PropertyType,
                                    propertyName,
                                    false,
                                    null,
                                    null);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            properties.Add(propertyName);
                            propertiesTouched.Add(propertyName);
                            expressions.Add(assignment.Rhs);
                            wideners.Add(widener);
                        }
                        else if (lhs is ExprAssignmentLHSIdentWSubprop subprop) {
                            throw new ExprValidationException("Property '" + subprop.SubpropertyName + "' is not available for write access");
                        }
                        else if (lhs is ExprAssignmentLHSArrayElement arrayElement) {
                            var propertyName = lhs.Ident;
                            var writableProperty = eventTypeSPI.GetWritableProperty(propertyName);
                            if (writableProperty == null) {
                                throw new ExprValidationException("Property '" + propertyName + "' is not available for write access");
                            }

                            if (!writableProperty.PropertyType.IsArray) {
                                throw new ExprValidationException("Property '" + propertyName + "' type is not array");
                            }

                            TypeWidenerSPI widener;
                            try {
                                widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                                    ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignment.Rhs),
                                    assignment.Rhs.Forge.EvaluationType,
                                    writableProperty.PropertyType.GetElementType(),
                                    propertyName,
                                    false,
                                    null,
                                    null);
                            }
                            catch (TypeWidenerException ex) {
                                throw new ExprValidationException(ex.Message, ex);
                            }

                            var special = new InternalEventRouterWriterArrayElementForge(
                                arrayElement.IndexExpression,
                                assignment.Rhs,
                                widener,
                                propertyName);
                            specialWriters.Add(special);
                        }
                        else {
                            throw new IllegalStateException("Unrecognized left hande side assignment " + lhs);
                        }
                    }
                    else if (assignmentDesc is ExprAssignmentCurly curly) {
                        var special = new InternalEventRouterWriterCurlyForge(curly.Expression);
                        specialWriters.Add(special);
                    }
                    else {
                        throw new IllegalStateException("Unrecognized assignment " + assignmentDesc);
                    }
                }
                catch (ExprValidationException ex) {
                    throw new ExprValidationException(
                        "Failed to validate assignment expression '" +
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(assignmentDesc.OriginalExpression) +
                        "': " +
                        ex.Message,
                        ex);
                }
            }

            // check copy-able
            var copyMethod = eventTypeSPI.GetCopyMethodForge(propertiesTouched.ToArray());
            if (copyMethod == null) {
                throw new ExprValidationException(
                    "The update-clause requires the underlying event representation to support copy (via Serializable by default)");
            }

            return new InternalEventRouterDescForge(
                copyMethod,
                wideners.ToArray(),
                eventType,
                annotations,
                desc.OptionalWhereClause,
                properties.ToArray(),
                expressions.ToArray(),
                specialWriters.ToArray());
        }
Пример #23
0
        public EvalSelectNoWildcardAvro(
            SelectExprContext selectExprContext,
            EventType resultEventType,
            string statementName,
            string engineURI)
        {
            _selectExprContext = selectExprContext;
            _resultEventType = (AvroEventType) resultEventType;

            _evaluator = new ExprEvaluator[selectExprContext.ExpressionNodes.Length];
            var typeWidenerCustomizer =
                selectExprContext.EventAdapterService.GetTypeWidenerCustomizer(resultEventType);
            for (var i = 0; i < _evaluator.Length; i++)
            {
                var eval = selectExprContext.ExpressionNodes[i];
                _evaluator[i] = eval;

                if (eval is SelectExprProcessorEvalByGetterFragment)
                {
                    _evaluator[i] = HandleFragment((SelectExprProcessorEvalByGetterFragment) eval);
                }
                else if (eval is SelectExprProcessorEvalStreamInsertUnd)
                {
                    var und = (SelectExprProcessorEvalStreamInsertUnd) eval;
                    _evaluator[i] = new ProxyExprEvaluator
                    {
                        ProcEvaluate = (evaluateParams) =>
                        {
                            var @event = evaluateParams.EventsPerStream[und.StreamNum];
                            if (@event == null)
                            {
                                return null;
                            }
                            return @event.Underlying;
                        },
                        ProcReturnType = () => { return typeof (GenericRecord); }
                    };
                }
                else if (eval is SelectExprProcessorEvalTypableMap)
                {
                    var typableMap = (SelectExprProcessorEvalTypableMap) eval;
                    _evaluator[i] = new SelectExprProcessorEvalAvroMapToAvro(
                        typableMap.InnerEvaluator, ((AvroEventType) resultEventType).SchemaAvro,
                        selectExprContext.ColumnNames[i]);
                }
                else if (eval is SelectExprProcessorEvalStreamInsertNamedWindow)
                {
                    var nw = (SelectExprProcessorEvalStreamInsertNamedWindow) eval;
                    _evaluator[i] = new ProxyExprEvaluator
                    {
                        ProcEvaluate = (evaluateParams) =>
                        {
                            var @event = evaluateParams.EventsPerStream[nw.StreamNum];
                            if (@event == null)
                            {
                                return null;
                            }
                            return @event.Underlying;
                        },
                        ProcReturnType = () => { return typeof (GenericRecord); }
                    };
                }
                else if (eval.ReturnType != null && eval.ReturnType.IsArray)
                {
                    var widener = TypeWidenerFactory.GetArrayToCollectionCoercer(eval.ReturnType.GetElementType());
                    //if (eval.ReturnType == typeof (byte[]))
                    //{
                    //    widener = TypeWidenerFactory.BYTE_ARRAY_TO_BYTE_BUFFER_COERCER;
                    //}
                    _evaluator[i] = new SelectExprProcessorEvalAvroArrayCoercer(eval, widener);
                }
                else
                {
                    var propertyName = selectExprContext.ColumnNames[i];
                    var propertyType = resultEventType.GetPropertyType(propertyName);
                    var widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        propertyName, eval.ReturnType, propertyType, propertyName, true, typeWidenerCustomizer,
                        statementName, engineURI);
                    if (widener != null)
                    {
                        _evaluator[i] = new SelectExprProcessorEvalAvroArrayCoercer(eval, widener);
                    }
                }
            }
        }
Пример #24
0
        public static SelectExprProcessorForge Make(
            EventType[] eventTypes,
            SelectExprForgeContext selectExprForgeContext,
            int streamNumber,
            EventType targetType,
            ExprNode[] exprNodes,
            ImportServiceCompileTime classpathImportService,
            string statementName)
        {
            var jsonResultType = (JsonEventType)targetType;
            var jsonStreamType = (JsonEventType)eventTypes[streamNumber];

            // (A) fully assignment-compatible: same number, name and type of fields, no additional expressions: Straight repackage
            if (jsonResultType.IsDeepEqualsConsiderOrder(jsonStreamType) && selectExprForgeContext.ExprForges.Length == 0)
            {
                return(new JsonInsertProcessorStraightFieldAssign(streamNumber, jsonStreamType, jsonResultType));
            }

            // (B) not completely assignable: find matching properties
            var writables = EventTypeUtility.GetWriteableProperties(jsonResultType, true, false);
            var items     = new List <Item>();
            var written   = new List <WriteablePropertyDescriptor>();

            // find the properties coming from the providing source stream
            foreach (var writeable in writables)
            {
                var propertyName = writeable.PropertyName;

                var fieldSource = jsonStreamType.Detail.FieldDescriptors.Get(propertyName);
                var fieldTarget = jsonResultType.Detail.FieldDescriptors.Get(propertyName);

                if (fieldSource != null)
                {
                    var setOneType      = jsonStreamType.Types.Get(propertyName);
                    var setTwoType      = jsonResultType.Types.Get(propertyName);
                    var setTwoTypeFound = jsonResultType.Types.ContainsKey(propertyName);
                    var message         = BaseNestableEventUtil.ComparePropType(propertyName, setOneType, setTwoType, setTwoTypeFound, jsonResultType.Name);
                    if (message != null)
                    {
                        throw new ExprValidationException(message.Message, message);
                    }
                    items.Add(new Item(fieldTarget, fieldSource, null, null));
                    written.Add(writeable);
                }
            }

            // find the properties coming from the expressions of the select clause
            for (var i = 0; i < selectExprForgeContext.ExprForges.Length; i++)
            {
                var columnName = selectExprForgeContext.ColumnNames[i];
                var forge      = selectExprForgeContext.ExprForges[i];
                var exprNode   = exprNodes[i];

                var writable = FindWritable(columnName, writables);
                if (writable == null)
                {
                    throw new ExprValidationException("Failed to find column '" + columnName + "' in target type '" + jsonResultType.Name + "'");
                }
                var fieldTarget = jsonResultType.Detail.FieldDescriptors.Get(writable.PropertyName);

                TypeWidenerSPI widener;
                try {
                    widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(exprNode),
                        exprNode.Forge.EvaluationType,
                        writable.PropertyType,
                        columnName,
                        false,
                        null,
                        statementName);
                } catch (TypeWidenerException ex) {
                    throw new ExprValidationException(ex.Message, ex);
                }

                items.Add(new Item(fieldTarget, null, forge, widener));
                written.Add(writable);
            }

            // make manufacturer
            var itemsArr = items.ToArray();

            return(new JsonInsertProcessorExpressions(streamNumber, itemsArr, jsonStreamType, jsonResultType));
        }