internal static void RunEquivalent( RegressionEnvironment env, string before, string after) { var hook = "@Hook(HookType=" + typeof(HookType).FullName + ".INTERNAL_COMPILE,Hook='" + SupportStatementCompileHook.ResetGetClassName() + "')"; var epl = hook + "@Name('s0') select * from SupportBean#keepall " + "match_recognize (" + " measures A as a" + " pattern (" + before + ")" + " define" + " A as A.TheString like \"A%\"" + ")"; var model = env.EplToModel(epl); env.CompileDeploy(model); env.UndeployAll(); var spec = SupportStatementCompileHook.GetSpecs()[0]; RowRecogExprNode expanded = null; try { expanded = RowRecogPatternExpandUtil.Expand( spec.Raw.MatchRecognizeSpec.Pattern, null); } catch (ExprValidationException e) { Assert.Fail(e.Message); } var writer = new StringWriter(); expanded.ToEPL(writer, RowRecogExprNodePrecedenceEnum.MINIMUM); Assert.AreEqual(after, writer.ToString()); }
public static StatementSpecCompiledDesc Compile( StatementSpecRaw spec, Compilable compilable, bool isSubquery, bool isOnDemandQuery, Attribute[] annotations, IList<ExprSubselectNode> subselectNodes, IList<ExprTableAccessNode> tableAccessNodes, StatementRawInfo statementRawInfo, StatementCompileTimeServices compileTimeServices) { IList<StreamSpecCompiled> compiledStreams; ISet<string> eventTypeReferences = new HashSet<string>(); IList<StmtClassForgeableFactory> additionalForgeables = new List<StmtClassForgeableFactory>(2); if (!isOnDemandQuery && spec.FireAndForgetSpec != null) { throw new StatementSpecCompileException( "Provided EPL expression is an on-demand query expression (not a continuous query)", compilable.ToEPL()); } // If not using a join and not specifying a data window, make the where-clause, if present, the filter of the stream // if selecting using filter spec, and not subquery in where clause if (spec.StreamSpecs.Count == 1 && spec.StreamSpecs[0] is FilterStreamSpecRaw && spec.StreamSpecs[0].ViewSpecs.Length == 0 && spec.WhereClause != null && spec.OnTriggerDesc == null && !isSubquery && !isOnDemandQuery && (tableAccessNodes == null || tableAccessNodes.IsEmpty())) { bool disqualified; ExprNode whereClause = spec.WhereClause; var visitorX = new ExprNodeSubselectDeclaredDotVisitor(); whereClause.Accept(visitorX); disqualified = visitorX.Subselects.Count > 0 || HintEnum.DISABLE_WHEREEXPR_MOVETO_FILTER.GetHint(annotations) != null; if (!disqualified) { var viewResourceVisitor = new ExprNodeViewResourceVisitor(); whereClause.Accept(viewResourceVisitor); disqualified = viewResourceVisitor.ExprNodes.Count > 0; } var streamSpec = (FilterStreamSpecRaw) spec.StreamSpecs[0]; if (streamSpec.RawFilterSpec.OptionalPropertyEvalSpec != null) { disqualified = true; } if (!disqualified) { spec.WhereClause = null; streamSpec.RawFilterSpec.FilterExpressions.Add(whereClause); } } // compile select-clause var selectClauseCompiled = CompileSelectClause(spec.SelectClauseSpec); // Determine subselects in filter streams, these may need special handling for locking var visitor = new ExprNodeSubselectDeclaredDotVisitor(); try { StatementSpecRawWalkerSubselectAndDeclaredDot.WalkStreamSpecs(spec, visitor); } catch (ExprValidationException ex) { throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL()); } foreach (var subselectNode in visitor.Subselects) { subselectNode.IsFilterStreamSubselect = true; } // Determine subselects for compilation, and lambda-expression shortcut syntax for named windows visitor.Reset(); GroupByClauseExpressions groupByRollupExpressions; try { StatementSpecRawWalkerSubselectAndDeclaredDot.WalkSubselectAndDeclaredDotExpr(spec, visitor); var expressionCopier = new ExpressionCopier( spec, statementRawInfo.OptionalContextDescriptor, compileTimeServices, visitor); groupByRollupExpressions = GroupByExpressionHelper.GetGroupByRollupExpressions( spec.GroupByExpressions, spec.SelectClauseSpec, spec.HavingClause, spec.OrderByList, expressionCopier); } catch (ExprValidationException ex) { throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL()); } // Expand match-recognize patterns if (spec.MatchRecognizeSpec != null) { RowRecogExprNode expandedPatternNode; try { var copier = new ExpressionCopier( spec, statementRawInfo.OptionalContextDescriptor, compileTimeServices, visitor); expandedPatternNode = RowRecogPatternExpandUtil.Expand(spec.MatchRecognizeSpec.Pattern, copier); } catch (ExprValidationException ex) { throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL()); } spec.MatchRecognizeSpec.Pattern = expandedPatternNode; } if (isSubquery && !visitor.Subselects.IsEmpty()) { throw new StatementSpecCompileException( "Invalid nested subquery, subquery-within-subquery is not supported", compilable.ToEPL()); } foreach (var subselectNode in visitor.Subselects) { if (!subselectNodes.Contains(subselectNode)) { subselectNodes.Add(subselectNode); } } // Compile subselects found var subselectNumber = 0; foreach (var subselect in subselectNodes) { var raw = subselect.StatementSpecRaw; var desc = Compile( raw, compilable, true, isOnDemandQuery, annotations, Collections.GetEmptyList<ExprSubselectNode>(), Collections.GetEmptyList<ExprTableAccessNode>(), statementRawInfo, compileTimeServices); additionalForgeables.AddAll(desc.AdditionalForgeables); subselect.SetStatementSpecCompiled(desc.Compiled, subselectNumber); subselectNumber++; } // Set table-access number var tableAccessNumber = 0; foreach (var tableAccess in tableAccessNodes) { tableAccess.TableAccessNumber = tableAccessNumber; tableAccessNumber++; } // compile each stream used try { compiledStreams = new List<StreamSpecCompiled>(spec.StreamSpecs.Count); var streamNum = 0; foreach (var rawSpec in spec.StreamSpecs) { streamNum++; var desc = StreamSpecCompiler.Compile( rawSpec, eventTypeReferences, spec.InsertIntoDesc != null, spec.StreamSpecs.Count > 1, false, spec.OnTriggerDesc != null, rawSpec.OptionalStreamName, streamNum, statementRawInfo, compileTimeServices); additionalForgeables.AddAll(desc.AdditionalForgeables); compiledStreams.Add(desc.StreamSpecCompiled); } } catch (ExprValidationException ex) { if (ex.Message == null) { throw new StatementSpecCompileException( "Unexpected exception compiling statement, please consult the log file and report the exception", ex, compilable.ToEPL()); } throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL()); } catch (EPException ex) { throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL()); } catch (Exception ex) { var text = "Unexpected error compiling statement"; Log.Error(text, ex); throw new StatementSpecCompileException( text + ": " + ex.GetType().Name + ":" + ex.Message, ex, compilable.ToEPL()); } var compiled = new StatementSpecCompiled( spec, compiledStreams.ToArray(), selectClauseCompiled, annotations, groupByRollupExpressions, subselectNodes, visitor.DeclaredExpressions, tableAccessNodes); return new StatementSpecCompiledDesc(compiled, additionalForgeables); }