Esempio n. 1
0
        private static WriteablePropertyDescriptor[] SetupProperties(string[] propertyNamesOffered, EventType outputEventType, StatementContext statementContext)
        {
            var writeables    = statementContext.EventAdapterService.GetWriteableProperties(outputEventType, false);
            var writablesList = new List <WriteablePropertyDescriptor>();

            for (var i = 0; i < propertyNamesOffered.Length; i++)
            {
                var propertyName = propertyNamesOffered[i];
                WriteablePropertyDescriptor writable = EventTypeUtility.FindWritable(propertyName, writeables);
                if (writable == null)
                {
                    throw new ExprValidationException("Failed to find writable property '" + propertyName + "' for event type '" + outputEventType.Name + "'");
                }
                writablesList.Add(writable);
            }

            return(writablesList.ToArray());
        }
Esempio n. 2
0
        private void RunAssertion(
            RegressionEnvironment env,
            string epl,
            Consumer <object> underlyingAssertion)
        {
            env.CompileDeploy("@public @name('schema') " + epl);

            var type = (EventTypeSPI)env.Deployment.GetDeployment(env.DeploymentId("schema")).Statements[0].EventType;

            var writables = EventTypeUtility.GetWriteableProperties(type, true, true);
            var props     = new WriteablePropertyDescriptor[2];

            props[0] = FindProp(writables, "P1");
            props[1] = FindProp(writables, "P2");

            var spi = (EPRuntimeSPI)env.Runtime;
            EventBeanManufacturer manufacturer;

            var forge = EventTypeUtility.GetManufacturer(
                type,
                props,
                spi.ServicesContext.ImportServiceRuntime,
                true,
                spi.ServicesContext.EventTypeAvroHandler);

            manufacturer = forge.GetManufacturer(spi.ServicesContext.EventBeanTypedEventFactory);

            var @event = manufacturer.Make(new object[] { "a", 1 });

            underlyingAssertion.Invoke(@event.Underlying);
            Assert.AreSame(@event.EventType, type);

            var underlying = manufacturer.MakeUnderlying(new object[] { "a", 1 });

            underlyingAssertion.Invoke(underlying);

            env.UndeployAll();
        }
        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));
        }
        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));
        }
Esempio n. 5
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));
        }
        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);
        }