public override EventType[] GetAddStreamTypes( string enumMethodUsedName, IList<string> goesToNames, EventType inputEventType, Type collectionComponentType, IList<ExprDotEvalParam> bodiesAndParameters, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { EventType evalEventType; if (inputEventType == null) { evalEventType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[1], collectionComponentType, statementRawInfo, services); } else { evalEventType = inputEventType; } var initializationType = bodiesAndParameters[0].BodyForge.EvaluationType; EventType typeResult = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[0], initializationType, statementRawInfo, services); return new[] {typeResult, evalEventType}; }
public override EventType[] GetAddStreamTypes( string enumMethodUsedName, IList<string> goesToNames, EventType inputEventType, Type collectionComponentType, IList<ExprDotEvalParam> bodiesAndParameters, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { EventType firstParamType; if (inputEventType == null) { firstParamType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[0], collectionComponentType, statementRawInfo, services); } else { firstParamType = inputEventType; } if (goesToNames.Count == 1) { return new EventType[] {firstParamType}; } var indexEventType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[1], typeof(int), statementRawInfo, services); return new EventType[] {firstParamType, indexEventType}; }
public override EventType[] GetAddStreamTypes( string enumMethodUsedName, IList <string> goesToNames, EventType inputEventType, Type collectionComponentType, IList <ExprDotEvalParam> bodiesAndParameters, EventAdapterService eventAdapterService) { EventType evalEventType; if (inputEventType == null) { evalEventType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[1], collectionComponentType, eventAdapterService); } else { evalEventType = inputEventType; } Type initializationType = bodiesAndParameters[0].BodyEvaluator.ReturnType; EventType typeResult = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[0], initializationType, eventAdapterService); return(new EventType[] { typeResult, evalEventType }); }
public EnumForgeLambdaDesc GetLambdaStreamTypesForParameter(int parameterNum) { var desc = _footprint.Parameters[parameterNum]; if (desc.LambdaParamNum == 0) { return new EnumForgeLambdaDesc(new EventType[0], new string[0]); } var param = _parameters[parameterNum]; if (!(param is ExprLambdaGoesNode)) { throw new IllegalStateException("Parameter " + parameterNum + " is not a lambda parameter"); } var goes = (ExprLambdaGoesNode) param; var goesToNames = goes.GoesToNames; // we allocate types for scalar-value-input and index-lambda-parameter-type; for event-input we use the existing input event type var types = new EventType[desc.LambdaParamNum]; var names = new string[desc.LambdaParamNum]; for (var i = 0; i < types.Length; i++) { // obtain lambda parameter type var lambdaParamType = _mode.LambdaParameters.Invoke(new EnumMethodLambdaParameterDescriptor(parameterNum, i)); if (lambdaParamType is EnumMethodLambdaParameterTypeValue) { if (_inputEventType == null) { types[i] = ExprDotNodeUtility.MakeTransientOAType(_enumMethodUsedName, goesToNames[i], _collectionComponentType, _raw, _services); } else { types[i] = _inputEventType; } } else if (lambdaParamType is EnumMethodLambdaParameterTypeIndex || lambdaParamType is EnumMethodLambdaParameterTypeSize) { types[i] = ExprDotNodeUtility.MakeTransientOAType(_enumMethodUsedName, goesToNames[i], typeof(int), _raw, _services); } else if (lambdaParamType is EnumMethodLambdaParameterTypeStateGetter) { var getter = (EnumMethodLambdaParameterTypeStateGetter) lambdaParamType; types[i] = ExprDotNodeUtility.MakeTransientOAType(_enumMethodUsedName, goesToNames[i], getter.Type, _raw, _services); } else { throw new UnsupportedOperationException("Unrecognized lambda parameter type " + lambdaParamType); } if (types[i] == _inputEventType) { names[i] = goesToNames[i]; } else { names[i] = types[i].Name; } } return new EnumForgeLambdaDesc(types, names); }
public override EnumForgeDescFactory GetForgeFactory( DotMethodFP footprint, IList <ExprNode> parameters, EnumMethodEnum enumMethod, string enumMethodUsedName, EventType inputEventType, Type collectionComponentType, ExprValidationContext validationContext) { var goesNode = (ExprLambdaGoesNode)parameters[1]; var numParameters = goesNode.GoesToNames.Count; var firstName = goesNode.GoesToNames[0]; var secondName = goesNode.GoesToNames[1]; IDictionary <string, object> fields = new Dictionary <string, object>(); var initializationType = parameters[0].Forge.EvaluationType; fields.Put(firstName, initializationType); if (inputEventType == null) { fields.Put(secondName, collectionComponentType); } if (numParameters > 2) { fields.Put(goesNode.GoesToNames[2], typeof(int)); if (numParameters > 3) { fields.Put(goesNode.GoesToNames[3], typeof(int)); } } var evalEventType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fields, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); if (inputEventType == null) { return(new EnumForgeDescFactoryAggregateScalar(evalEventType)); } return(new EnumForgeDescFactoryAggregateEvent(evalEventType, inputEventType, secondName, numParameters)); }
public override EventType[] GetAddStreamTypes( string enumMethodUsedName, IList <string> goesToNames, EventType inputEventType, Type collectionComponentType, IList <ExprDotEvalParam> bodiesAndParameters, EventAdapterService eventAdapterService) { EventType firstParamType; if (inputEventType == null) { firstParamType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[0], collectionComponentType, eventAdapterService); } else { firstParamType = inputEventType; } if (goesToNames.Count == 1) { return(new EventType[] { firstParamType }); } ObjectArrayEventType indexEventType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, goesToNames[1], typeof(int), eventAdapterService); return(new EventType[] { firstParamType, indexEventType }); }
public override EnumForgeDescFactory GetForgeFactory( DotMethodFP footprint, IList <ExprNode> parameters, EnumMethodEnum enumMethod, string enumMethodUsedName, EventType inputEventType, Type collectionComponentType, ExprValidationContext validationContext) { if (parameters.IsEmpty()) { var typeX = InitAndNoParamsReturnType(inputEventType, collectionComponentType); return(new ThreeFormNoParamFactory(typeX, NoParamsForge(enumMethod, typeX, validationContext.StatementCompileTimeService))); } var goesNode = (ExprLambdaGoesNode)parameters[0]; var goesToNames = goesNode.GoesToNames; if (inputEventType != null) { var streamName = goesToNames[0]; if (goesToNames.Count == 1) { return(new ThreeFormEventPlainFactory( InitAndSingleParamReturnType(inputEventType, collectionComponentType), inputEventType, streamName, SingleParamEventPlain(enumMethod))); } IDictionary <string, object> fieldsX = new LinkedHashMap <string, object>(); fieldsX.Put(goesToNames[1], typeof(int?)); if (goesToNames.Count > 2) { fieldsX.Put(goesToNames[2], typeof(int?)); } var fieldType = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fieldsX, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); return(new ThreeFormEventPlusFactory( InitAndSingleParamReturnType(inputEventType, collectionComponentType), inputEventType, streamName, fieldType, goesToNames.Count, SingleParamEventPlus(enumMethod))); } var fields = new LinkedHashMap <string, object>(); fields.Put(goesToNames[0], collectionComponentType); if (goesToNames.Count > 1) { fields.Put(goesToNames[1], typeof(int?)); } if (goesToNames.Count > 2) { fields.Put(goesToNames[2], typeof(int?)); } var type = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fields, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); return(new ThreeFormScalarFactory( InitAndSingleParamReturnType(inputEventType, collectionComponentType), type, goesToNames.Count, SingleParamScalar(enumMethod))); }
public override EnumForgeDescFactory GetForgeFactory( DotMethodFP footprint, IList <ExprNode> parameters, EnumMethodEnum enumMethod, string enumMethodUsedName, EventType inputEventType, Type collectionComponentType, ExprValidationContext validationContext) { if (parameters.Count < 2) { throw new IllegalStateException(); } EPType returnType = ReturnType(inputEventType, collectionComponentType); ExprLambdaGoesNode lambdaFirst = (ExprLambdaGoesNode)parameters[0]; ExprLambdaGoesNode lambdaSecond = (ExprLambdaGoesNode)parameters[1]; if (lambdaFirst.GoesToNames.Count != lambdaSecond.GoesToNames.Count) { throw new ExprValidationException( "Enumeration method '" + enumMethodUsedName + "' expected the same number of parameters for both the key and the value expression"); } int numParameters = lambdaFirst.GoesToNames.Count; if (inputEventType != null) { string streamNameFirst = lambdaFirst.GoesToNames[0]; string streamNameSecond = lambdaSecond.GoesToNames[0]; if (numParameters == 1) { return(new TwoLambdaThreeFormEventPlainFactory(inputEventType, streamNameFirst, streamNameSecond, returnType, TwoParamEventPlain())); } IDictionary <string, object> fieldsFirst = new Dictionary <string, object>(); IDictionary <string, object> fieldsSecond = new Dictionary <string, object>(); fieldsFirst.Put(lambdaFirst.GoesToNames[1], typeof(int?)); fieldsSecond.Put(lambdaSecond.GoesToNames[1], typeof(int?)); if (numParameters > 2) { fieldsFirst.Put(lambdaFirst.GoesToNames[2], typeof(int?)); fieldsSecond.Put(lambdaSecond.GoesToNames[2], typeof(int?)); } ObjectArrayEventType typeFirst = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fieldsFirst, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); ObjectArrayEventType typeSecond = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fieldsSecond, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); return(new TwoLambdaThreeFormEventPlusFactory( inputEventType, streamNameFirst, streamNameSecond, typeFirst, typeSecond, lambdaFirst.GoesToNames.Count, returnType, TwoParamEventPlus())); } else { IDictionary <string, object> fieldsFirst = new Dictionary <string, object>(); IDictionary <string, object> fieldsSecond = new Dictionary <string, object>(); fieldsFirst.Put(lambdaFirst.GoesToNames[0], collectionComponentType); fieldsSecond.Put(lambdaSecond.GoesToNames[0], collectionComponentType); if (numParameters > 1) { fieldsFirst.Put(lambdaFirst.GoesToNames[1], typeof(int?)); fieldsSecond.Put(lambdaSecond.GoesToNames[1], typeof(int?)); } if (numParameters > 2) { fieldsFirst.Put(lambdaFirst.GoesToNames[2], typeof(int?)); fieldsSecond.Put(lambdaSecond.GoesToNames[2], typeof(int?)); } ObjectArrayEventType typeFirst = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fieldsFirst, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); ObjectArrayEventType typeSecond = ExprDotNodeUtility.MakeTransientOAType( enumMethodUsedName, fieldsSecond, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); return(new TwoLambdaThreeFormScalarFactory( typeFirst, typeSecond, lambdaFirst.GoesToNames.Count, returnType, TwoParamScalar())); } }
public override ExprNode Validate(ExprValidationContext validationContext) { this.exprValidationContext = validationContext; var prototype = PrototypeWVisibility; if (prototype.IsAlias) { if (!ChainParameters.IsEmpty()) { throw new ExprValidationException("Expression '" + prototype.Name + " is an expression-alias and does not allow parameters"); } try { ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.ALIASEXPRBODY, ExpressionBodyCopy, validationContext); } catch (ExprValidationException ex) { var message = "Failed to validate expression alias '" + prototype.Name + "': " + ex.Message; throw new ExprValidationException(message, ex); } forge = ExpressionBodyCopy.Forge; return null; } if (forge != null) { return null; // already evaluated } if (ChildNodes.Length > 0) { throw new IllegalStateException("Execution node has its own child nodes"); } // validate chain IList<ExprNode> validated = new List<ExprNode>(); foreach (var expr in ChainParameters) { validated.Add( ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.DECLAREDEXPRPARAM, expr, validationContext)); } ChainParameters = validated; // validate parameter count CheckParameterCount(); // collect event and value (non-event) parameters List<int> valueParameters = new List<int>(); List<int> eventParameters = new List<int>(); for (int i = 0; i < prototype.ParametersNames.Length; i++) { ExprNode parameter = ChainParameters[i]; if (parameter is ExprWildcard) { if (validationContext.StreamTypeService.EventTypes.Length != 1) { throw new ExprValidationException("Expression '" + prototype.Name + "' only allows a wildcard parameter if there is a single stream available, please use a stream or tag name instead"); } } if (IsEventProviding(parameter, validationContext)) { eventParameters.Add(i); } else { valueParameters.Add(i); } } // determine value event type for holding non-event parameter values, if any ObjectArrayEventType valueEventType = null; List<ExprNode> valueExpressions = new List<ExprNode>(valueParameters.Count); if (!valueParameters.IsEmpty()) { var valuePropertyTypes = new LinkedHashMap<string, object>(); foreach (int index in valueParameters) { String name = prototype.ParametersNames[index]; ExprNode expr = ChainParameters[index]; var result = Boxing.GetBoxedType(expr.Forge.EvaluationType); valuePropertyTypes.Put(name, result); valueExpressions.Add(expr); } valueEventType = ExprDotNodeUtility.MakeTransientOAType( PrototypeWVisibility.Name, valuePropertyTypes, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); } // create context for expression body int numEventTypes = eventParameters.Count + (valueEventType == null ? 0 : 1); EventType[] eventTypes = new EventType[numEventTypes]; String[] streamNames = new String[numEventTypes]; bool[] isIStreamOnly = new bool[numEventTypes]; ExprEnumerationForge[] eventEnumerationForges = new ExprEnumerationForge[numEventTypes]; allStreamIdsMatch = true; int offsetEventType = 0; if (valueEventType != null) { offsetEventType = 1; eventTypes[0] = valueEventType; streamNames[0] = INTERNAL_VALUE_STREAMNAME; isIStreamOnly[0] = true; allStreamIdsMatch = false; } bool forceOptionalStream = false; foreach (int index in eventParameters) { ExprNode parameter = ChainParameters[index]; streamNames[offsetEventType] = prototype.ParametersNames[index]; int streamId; bool istreamOnlyFlag; ExprEnumerationForge forge; if (parameter is ExprEnumerationForgeProvider) { ExprEnumerationForgeProvider enumerationForgeProvider = (ExprEnumerationForgeProvider) parameter; ExprEnumerationForgeDesc desc = enumerationForgeProvider.GetEnumerationForge( validationContext.StreamTypeService, validationContext.ContextDescriptor); forge = desc.Forge; streamId = desc.DirectIndexStreamNumber; istreamOnlyFlag = desc.IsIstreamOnly; } else { forge = (ExprEnumerationForge) parameter.Forge; istreamOnlyFlag = false; streamId = -1; forceOptionalStream = true; // since they may return null, i.e. subquery returning no row or multiple rows etc. } isIStreamOnly[offsetEventType] = istreamOnlyFlag; eventEnumerationForges[offsetEventType] = forge; eventTypes[offsetEventType] = forge.GetEventTypeSingle(validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); if (streamId != index) { allStreamIdsMatch = false; } offsetEventType++; } var streamTypeService = validationContext.StreamTypeService; var optionalStream = forceOptionalStream || streamTypeService.IsOptionalStreams; var copyTypes = new StreamTypeServiceImpl( eventTypes, streamNames, isIStreamOnly, streamTypeService.IsOnDemandStreams, optionalStream); copyTypes.RequireStreamNames = true; // validate expression body in this context try { var expressionBodyContext = new ExprValidationContext(copyTypes, validationContext); ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.DECLAREDEXPRBODY, ExpressionBodyCopy, expressionBodyContext); } catch (ExprValidationException ex) { var message = "Failed to validate expression declaration '" + prototype.Name + "': " + ex.Message; throw new ExprValidationException(message, ex); } // analyze child node var summaryVisitor = new ExprNodeSummaryVisitor(); ExpressionBodyCopy.Accept(summaryVisitor); var isCache = !(summaryVisitor.HasAggregation || summaryVisitor.HasPreviousPrior); isCache &= validationContext.StatementCompileTimeService.Configuration.Compiler.Execution .IsEnabledDeclaredExprValueCache; // determine a suitable evaluation var audit = AuditEnum.EXPRDEF.GetAudit(validationContext.Annotations) != null; var statementName = validationContext.StatementName; if (ExpressionBodyCopy.Forge.ForgeConstantType.IsConstant) { // pre-evaluated forge = new ExprDeclaredForgeConstant( this, ExpressionBodyCopy.Forge.EvaluationType, prototype, ExpressionBodyCopy.Forge.ExprEvaluator.Evaluate(null, true, null), audit, statementName); } else if (valueEventType == null && prototype.ParametersNames.Length == 0 || allStreamIdsMatch && prototype.ParametersNames.Length == streamTypeService.EventTypes.Length) { forge = new ExprDeclaredForgeNoRewrite( this, ExpressionBodyCopy.Forge, isCache, audit, statementName); } else if (valueEventType == null) { forge = new ExprDeclaredForgeRewrite( this, ExpressionBodyCopy.Forge, isCache, eventEnumerationForges, audit, statementName); } else { // cache is always false forge = new ExprDeclaredForgeRewriteWValue( this, ExpressionBodyCopy.Forge, false, audit, statementName, eventEnumerationForges, valueEventType, valueExpressions); } return null; }