/// <summary> /// Compile a select clause allowing subselects. /// </summary> /// <param name="spec">to compile</param> /// <returns>select clause compiled</returns> /// <throws>ExprValidationException when validation fails</throws> private static SelectClauseSpecCompiled CompileSelectAllowSubselect(SelectClauseSpecRaw spec) { // Look for expressions with sub-selects in select expression list and filter expression // Recursively compile the statement within the statement. var visitor = new ExprNodeSubselectDeclaredDotVisitor(); IList<SelectClauseElementCompiled> selectElements = new List<SelectClauseElementCompiled>(); foreach (var raw in spec.SelectExprList) { if (raw is SelectClauseExprRawSpec) { var rawExpr = (SelectClauseExprRawSpec) raw; rawExpr.SelectExpression.Accept(visitor); selectElements.Add( new SelectClauseExprCompiledSpec( rawExpr.SelectExpression, rawExpr.OptionalAsName, rawExpr.OptionalAsName, rawExpr.IsEvents)); } else if (raw is SelectClauseStreamRawSpec) { var rawExpr = (SelectClauseStreamRawSpec) raw; selectElements.Add(new SelectClauseStreamCompiledSpec(rawExpr.StreamName, rawExpr.OptionalAsName)); } else if (raw is SelectClauseElementWildcard) { var wildcard = (SelectClauseElementWildcard) raw; selectElements.Add(wildcard); } else { throw new IllegalStateException("Unexpected select clause element class : " + raw.GetType().Name); } } return new SelectClauseSpecCompiled(selectElements.ToArray(), spec.IsDistinct); }
public static SelectClauseSpecCompiled CompileSelectClause(SelectClauseSpecRaw spec) { IList<SelectClauseElementCompiled> selectElements = new List<SelectClauseElementCompiled>(); foreach (var raw in spec.SelectExprList) { if (raw is SelectClauseExprRawSpec) { var rawExpr = (SelectClauseExprRawSpec) raw; selectElements.Add( new SelectClauseExprCompiledSpec( rawExpr.SelectExpression, rawExpr.OptionalAsName, rawExpr.OptionalAsName, rawExpr.IsEvents)); } else if (raw is SelectClauseStreamRawSpec) { var rawExpr = (SelectClauseStreamRawSpec) raw; selectElements.Add(new SelectClauseStreamCompiledSpec(rawExpr.StreamName, rawExpr.OptionalAsName)); } else if (raw is SelectClauseElementWildcard) { var wildcard = (SelectClauseElementWildcard) raw; selectElements.Add(wildcard); } else { throw new IllegalStateException("Unexpected select clause element class : " + raw.GetType().Name); } } return new SelectClauseSpecCompiled(selectElements.ToArray(), spec.IsDistinct); }
public CreateWindowCompileResult( FilterSpecCompiled filterSpecCompiled, SelectClauseSpecRaw selectClauseSpecRaw, EventType asEventType) { this.filterSpecCompiled = filterSpecCompiled; this.selectClauseSpecRaw = selectClauseSpecRaw; this.asEventType = asEventType; }
public CreateWindowCompileResult( FilterSpecCompiled filterSpecCompiled, SelectClauseSpecRaw selectClauseSpecRaw, EventType asEventType, IList<StmtClassForgeableFactory> additionalForgeables) { FilterSpecCompiled = filterSpecCompiled; SelectClauseSpecRaw = selectClauseSpecRaw; AsEventType = asEventType; AdditionalForgeables = additionalForgeables; }
public static GroupByClauseExpressions GetGroupByRollupExpressions( IList<GroupByClauseElement> groupByElements, SelectClauseSpecRaw selectClauseSpec, ExprNode optionalHavingNode, IList<OrderByItem> orderByList, ExpressionCopier expressionCopier) { if (groupByElements == null || groupByElements.Count == 0) { return null; } // walk group-by-elements, determine group-by expressions and rollup nodes var groupByExpressionInfo = GroupByToRollupNodes(groupByElements); // obtain expression nodes, collect unique nodes and assign index IList<ExprNode> distinctGroupByExpressions = new List<ExprNode>(); IDictionary<ExprNode, int> expressionToIndex = new Dictionary<ExprNode, int>(); foreach (var exprNode in groupByExpressionInfo.Expressions) { var found = false; for (var i = 0; i < distinctGroupByExpressions.Count; i++) { ExprNode other = distinctGroupByExpressions[i]; // find same expression if (ExprNodeUtilityCompare.DeepEquals(exprNode, other, false)) { expressionToIndex.Put(exprNode, i); found = true; break; } } // not seen before if (!found) { expressionToIndex.Put(exprNode, distinctGroupByExpressions.Count); distinctGroupByExpressions.Add(exprNode); } } // determine rollup, validate it is either (not both) var hasGroupingSet = false; var hasRollup = false; foreach (var element in groupByElements) { if (element is GroupByClauseElementGroupingSet) { hasGroupingSet = true; } if (element is GroupByClauseElementRollupOrCube) { hasRollup = true; } } // no-rollup or grouping-sets means simply validate ExprNode[] groupByExpressions = distinctGroupByExpressions.ToArray(); if (!hasRollup && !hasGroupingSet) { return new GroupByClauseExpressions(groupByExpressions); } // evaluate rollup node roots var nodes = groupByExpressionInfo.Nodes; var perNodeCombinations = new object[nodes.Count][]; var context = new GroupByRollupEvalContext(expressionToIndex); try { for (var i = 0; i < nodes.Count; i++) { GroupByRollupNodeBase node = nodes[i]; var combinations = node.Evaluate(context); perNodeCombinations[i] = new object[combinations.Count]; for (var j = 0; j < combinations.Count; j++) { perNodeCombinations[i][j] = combinations[j]; } } } catch (GroupByRollupDuplicateException ex) { if (ex.Indexes.Length == 0) { throw new ExprValidationException( "Failed to validate the group-by clause, found duplicate specification of the overall grouping '()'"); } var writer = new StringWriter(); var delimiter = ""; for (var i = 0; i < ex.Indexes.Length; i++) { writer.Write(delimiter); writer.Write( ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(groupByExpressions[ex.Indexes[i]])); delimiter = ", "; } throw new ExprValidationException( "Failed to validate the group-by clause, found duplicate specification of expressions (" + writer + ")"); } // enumerate combinations building an index list var combinationEnumeration = new CombinationEnumeration(perNodeCombinations); var combination = new SortedSet<int>(); var indexList = new LinkedHashSet<MultiKeyArrayInt>(); while (combinationEnumeration.MoveNext()) { combination.Clear(); object[] combinationOA = combinationEnumeration.Current; foreach (var indexes in combinationOA) { var indexarr = (int[]) indexes; foreach (var anIndex in indexarr) { combination.Add(anIndex); } } var indexArr = CollectionUtil.IntArray(combination); indexList.Add(new MultiKeyArrayInt(indexArr)); } // obtain rollup levels var rollupLevels = new int[indexList.Count][]; var count = 0; foreach (var mk in indexList) { rollupLevels[count++] = mk.Keys; } var numberOfLevels = rollupLevels.Length; if (numberOfLevels == 1 && rollupLevels[0].Length == 0) { throw new ExprValidationException( "Failed to validate the group-by clause, the overall grouping '()' cannot be the only grouping"); } // obtain select-expression copies for rewrite var expressions = selectClauseSpec.SelectExprList; var selects = new ExprNode[numberOfLevels][]; for (var i = 0; i < numberOfLevels; i++) { selects[i] = new ExprNode[expressions.Count]; for (var j = 0; j < expressions.Count; j++) { SelectClauseElementRaw selectRaw = expressions[j]; if (!(selectRaw is SelectClauseExprRawSpec)) { throw new ExprValidationException( "Group-by with rollup requires that the select-clause does not use wildcard"); } var compiled = (SelectClauseExprRawSpec) selectRaw; selects[i][j] = CopyVisitExpression(compiled.SelectExpression, expressionCopier); } } // obtain having-expression copies for rewrite ExprNode[] optHavingNodeCopy = null; if (optionalHavingNode != null) { optHavingNodeCopy = new ExprNode[numberOfLevels]; for (var i = 0; i < numberOfLevels; i++) { optHavingNodeCopy[i] = CopyVisitExpression(optionalHavingNode, expressionCopier); } } // obtain orderby-expression copies for rewrite ExprNode[][] optOrderByCopy = null; if (orderByList != null && orderByList.Count > 0) { optOrderByCopy = new ExprNode[numberOfLevels][]; for (var i = 0; i < numberOfLevels; i++) { optOrderByCopy[i] = new ExprNode[orderByList.Count]; for (var j = 0; j < orderByList.Count; j++) { OrderByItem element = orderByList[j]; optOrderByCopy[i][j] = CopyVisitExpression(element.ExprNode, expressionCopier); } } } return new GroupByClauseExpressions( groupByExpressions, rollupLevels, selects, optHavingNodeCopy, optOrderByCopy); }
// The create window command: // create window windowName[.window_view_list] as [select properties from] type // // This section expected s single FilterStreamSpecCompiled representing the selected type. // It creates a new event type representing the window type and a sets the type selected on the filter stream spec. protected internal static CreateWindowCompileResult HandleCreateWindow( StatementBaseInfo @base, StatementCompileTimeServices services) { var createWindowDesc = @base.StatementSpec.Raw.CreateWindowDesc; var columns = createWindowDesc.Columns; var typeName = createWindowDesc.WindowName; EventType targetType; // determine that the window name is not already in use as an event type name var existingType = services.EventTypeCompileTimeResolver.GetTypeByName(typeName); if (existingType != null && existingType.Metadata.TypeClass != EventTypeTypeClass.NAMED_WINDOW) { throw new ExprValidationException( "Error starting statement: An event type or schema by name '" + typeName + "' already exists"); } // Determine select-from var optionalSelectFrom = GetOptionalSelectFrom(createWindowDesc, services); // Create Map or Wrapper event type from the select clause of the window. // If no columns selected, simply create a wrapper type // Build a list of properties var newSelectClauseSpecRaw = new SelectClauseSpecRaw(); LinkedHashMap<string, object> properties; var hasProperties = false; if (columns != null && !columns.IsEmpty()) { properties = EventTypeUtility.BuildType( columns, null, services.ImportServiceCompileTime, services.EventTypeCompileTimeResolver); hasProperties = true; } else { if (optionalSelectFrom == null) { throw new IllegalStateException("Missing from-type information for create-window"); } // Validate the select expressions which consists of properties only var select = CompileLimitedSelect(optionalSelectFrom, @base, services); properties = new LinkedHashMap<string, object>(); foreach (var selectElement in select) { if (selectElement.FragmentType != null) { properties.Put(selectElement.AssignedName, selectElement.FragmentType); } else { properties.Put(selectElement.AssignedName, selectElement.SelectExpressionType); } // Add any properties to the new select clause for use by consumers to the statement itself newSelectClauseSpecRaw.Add( new SelectClauseExprRawSpec(new ExprIdentNodeImpl(selectElement.AssignedName), null, false)); hasProperties = true; } } // Create Map or Wrapper event type from the select clause of the window. // If no columns selected, simply create a wrapper type var isOnlyWildcard = @base.StatementSpec.Raw.SelectClauseSpec.IsOnlyWildcard; var isWildcard = @base.StatementSpec.Raw.SelectClauseSpec.IsUsingWildcard; var namedWindowVisibility = services.ModuleVisibilityRules.GetAccessModifierNamedWindow(@base, typeName); var additionalForgeables = new List<StmtClassForgeableFactory>(); try { if (isWildcard && !isOnlyWildcard) { var metadata = new EventTypeMetadata( typeName, @base.ModuleName, EventTypeTypeClass.NAMED_WINDOW, EventTypeApplicationType.WRAPPER, namedWindowVisibility, EventTypeBusModifier.NONBUS, false, EventTypeIdPair.Unassigned()); targetType = WrapperEventTypeUtil.MakeWrapper( metadata, optionalSelectFrom.EventType, properties, null, services.BeanEventTypeFactoryPrivate, services.EventTypeCompileTimeResolver); } else { // Some columns selected, use the types of the columns Func<EventTypeApplicationType, EventTypeMetadata> metadata = type => new EventTypeMetadata( typeName, @base.ModuleName, EventTypeTypeClass.NAMED_WINDOW, type, namedWindowVisibility, EventTypeBusModifier.NONBUS, false, EventTypeIdPair.Unassigned()); if (hasProperties && !isOnlyWildcard) { var compiledProperties = EventTypeUtility.CompileMapTypeProperties( properties, services.EventTypeCompileTimeResolver); var representation = EventRepresentationUtil.GetRepresentation( @base.StatementSpec.Annotations, services.Configuration, AssignedType.NONE); if (representation == EventUnderlyingType.MAP) { targetType = BaseNestableEventUtil.MakeMapTypeCompileTime( metadata.Invoke(EventTypeApplicationType.MAP), compiledProperties, null, null, null, null, services.BeanEventTypeFactoryPrivate, services.EventTypeCompileTimeResolver); } else if (representation == EventUnderlyingType.OBJECTARRAY) { targetType = BaseNestableEventUtil.MakeOATypeCompileTime( metadata.Invoke(EventTypeApplicationType.OBJECTARR), compiledProperties, null, null, null, null, services.BeanEventTypeFactoryPrivate, services.EventTypeCompileTimeResolver); } else if (representation == EventUnderlyingType.AVRO) { targetType = services.EventTypeAvroHandler.NewEventTypeFromNormalized( metadata.Invoke(EventTypeApplicationType.AVRO), services.EventTypeCompileTimeResolver, services.BeanEventTypeFactoryPrivate.EventBeanTypedEventFactory, compiledProperties, @base.StatementRawInfo.Annotations, null, null, null, @base.StatementName); } else if (representation == EventUnderlyingType.JSON) { EventTypeForgeablesPair pair = JsonEventTypeUtility.MakeJsonTypeCompileTimeNewType( metadata.Invoke(EventTypeApplicationType.JSON), compiledProperties, null, null, @base.StatementRawInfo, services); targetType = pair.EventType; additionalForgeables.AddRange(pair.AdditionalForgeables); } else { throw new IllegalStateException("Unrecognized representation " + representation); } } else { if (optionalSelectFrom == null) { throw new IllegalStateException("Missing from-type information for create-window"); } var selectFromType = optionalSelectFrom.EventType; // No columns selected, no wildcard, use the type as is or as a wrapped type if (selectFromType is ObjectArrayEventType) { var oaType = (ObjectArrayEventType) selectFromType; targetType = BaseNestableEventUtil.MakeOATypeCompileTime( metadata.Invoke(EventTypeApplicationType.OBJECTARR), oaType.Types, null, null, oaType.StartTimestampPropertyName, oaType.EndTimestampPropertyName, services.BeanEventTypeFactoryPrivate, services.EventTypeCompileTimeResolver); } else if (selectFromType is AvroSchemaEventType) { var avroSchemaEventType = (AvroSchemaEventType) selectFromType; var avro = new ConfigurationCommonEventTypeAvro(); avro.AvroSchema = avroSchemaEventType.Schema; targetType = services.EventTypeAvroHandler.NewEventTypeFromSchema( metadata.Invoke(EventTypeApplicationType.AVRO), services.BeanEventTypeFactoryPrivate.EventBeanTypedEventFactory, avro, null, null); } else if (selectFromType is JsonEventType) { JsonEventType jsonType = (JsonEventType) selectFromType; targetType = JsonEventTypeUtility.MakeJsonTypeCompileTimeExistingType( metadata.Invoke(EventTypeApplicationType.JSON), jsonType, services); } else if (selectFromType is MapEventType) { var mapType = (MapEventType) selectFromType; targetType = BaseNestableEventUtil.MakeMapTypeCompileTime( metadata.Invoke(EventTypeApplicationType.MAP), mapType.Types, null, null, mapType.StartTimestampPropertyName, mapType.EndTimestampPropertyName, services.BeanEventTypeFactoryPrivate, services.EventTypeCompileTimeResolver); } else if (selectFromType is BeanEventType) { var beanType = (BeanEventType) selectFromType; targetType = new BeanEventType( services.Container, beanType.Stem, metadata.Invoke(EventTypeApplicationType.CLASS), services.BeanEventTypeFactoryPrivate, null, null, beanType.StartTimestampPropertyName, beanType.EndTimestampPropertyName); } else { targetType = WrapperEventTypeUtil.MakeWrapper( metadata.Invoke(EventTypeApplicationType.WRAPPER), selectFromType, new Dictionary<string, object>(), null, services.BeanEventTypeFactoryPrivate, services.EventTypeCompileTimeResolver); } } } services.EventTypeCompileTimeRegistry.NewType(targetType); } catch (EPException ex) { throw new ExprValidationException(ex.Message, ex); } var filter = new FilterSpecCompiled(targetType, typeName, FilterSpecPlanForge.EMPTY, null); return new CreateWindowCompileResult( filter, newSelectClauseSpecRaw, optionalSelectFrom?.EventType, additionalForgeables); }