public override void Accept(ExprNodeVisitorWithParent visitor) { base.Accept(visitor); if (ChildNodes.Length == 0) { ExpressionBodyCopy.Accept(visitor); } }
public override void AcceptChildnodes( ExprNodeVisitorWithParent visitor, ExprNode parent) { base.AcceptChildnodes(visitor, parent); if (visitor.IsVisit(this) && ChildNodes.Length == 0) { ExpressionBodyCopy.Accept(visitor); } }
public void AcceptNoVisitParams(ExprNodeVisitorWithParent visitor) { base.Accept(visitor); if (ChildNodes.Length == 0) { ExpressionBodyCopy.Accept(visitor); } }
public override ExprNode Validate(ExprValidationContext validationContext) { var prototype = PrototypeWVisibility; if (prototype.IsAlias) { try { ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.ALIASEXPRBODY, ExpressionBodyCopy, validationContext); } catch (ExprValidationException ex) { var message = "Error validating 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(); // create context for expression body var eventTypes = new EventType[prototype.ParametersNames.Length]; var streamNames = new string[prototype.ParametersNames.Length]; var isIStreamOnly = new bool[prototype.ParametersNames.Length]; var streamsIdsPerStream = new int[prototype.ParametersNames.Length]; var allStreamIdsMatch = true; for (var i = 0; i < prototype.ParametersNames.Length; i++) { var parameter = ChainParameters[i]; streamNames[i] = prototype.ParametersNames[i]; if (parameter is ExprStreamUnderlyingNode) { var und = (ExprStreamUnderlyingNode) parameter; eventTypes[i] = validationContext.StreamTypeService.EventTypes[und.StreamId]; isIStreamOnly[i] = validationContext.StreamTypeService.IStreamOnly[und.StreamId]; streamsIdsPerStream[i] = und.StreamId; } else 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"); } eventTypes[i] = validationContext.StreamTypeService.EventTypes[0]; isIStreamOnly[i] = validationContext.StreamTypeService.IStreamOnly[0]; streamsIdsPerStream[i] = 0; } else { throw new ExprValidationException( "Expression '" + prototype.Name + "' requires a stream name as a parameter"); } if (streamsIdsPerStream[i] != i) { allStreamIdsMatch = false; } } var streamTypeService = validationContext.StreamTypeService; var copyTypes = new StreamTypeServiceImpl( eventTypes, streamNames, isIStreamOnly, streamTypeService.IsOnDemandStreams, streamTypeService.IsOptionalStreams); 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 = "Error validating 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 (prototype.ParametersNames.Length == 0 || allStreamIdsMatch && prototype.ParametersNames.Length == streamTypeService.EventTypes.Length) { forge = new ExprDeclaredForgeNoRewrite(this, ExpressionBodyCopy.Forge, isCache, audit, statementName); } else { forge = new ExprDeclaredForgeRewrite( this, ExpressionBodyCopy.Forge, isCache, streamsIdsPerStream, audit, statementName); } return null; }
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; }