private void UpdateInternal(EventBean[] eventsPerStream, ExprEvaluatorContext exprEvaluatorContext, EventBean target) { var evaluateParams = new EvaluateParams(eventsPerStream, true, exprEvaluatorContext); for (int i = 0; i < _updateItems.Length; i++) { EventBeanUpdateItem updateItem = _updateItems[i]; if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().QInfraUpdateRHSExpr(i, updateItem); } Object result = updateItem.Expression.Evaluate(evaluateParams); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().AInfraUpdateRHSExpr(result); } if (updateItem.OptionalWriter != null) { if (result == null && updateItem.IsNotNullableField) { Log.Warn("Null value returned by expression for assignment to property '" + updateItem.OptionalPropertyName + " is ignored as the property type is not nullable for expression"); continue; } if (updateItem.OptionalWidener != null) { result = updateItem.OptionalWidener.Invoke(result); } updateItem.OptionalWriter.Write(result, target); } } }
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)); }