PageRenderTime 4ms CodeModel.GetById 15ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/NEsper/NEsper/epl/spec/util/StatementSpecRawAnalyzer.cs

https://bitbucket.org/crackajaxx/nesper
C# | 520 lines | 469 code | 34 blank | 17 comment | 175 complexity | 896e64f8132430017160db318c3ee024 MD5 | raw file
  1///////////////////////////////////////////////////////////////////////////////////////
  2// Copyright (C) 2006-2015 Esper Team. All rights reserved.                           /
  3// http://esper.codehaus.org                                                          /
  4// ---------------------------------------------------------------------------------- /
  5// The software in this package is published under the terms of the GPL license       /
  6// a copy of which has been included with this distribution in the license.txt file.  /
  7///////////////////////////////////////////////////////////////////////////////////////
  8
  9using System.Collections.Generic;
 10
 11using com.espertech.esper.client;
 12using com.espertech.esper.compat.collections;
 13using com.espertech.esper.epl.expression.core;
 14using com.espertech.esper.epl.expression.visitor;
 15using com.espertech.esper.pattern;
 16
 17namespace com.espertech.esper.epl.spec.util
 18{
 19    public class StatementSpecRawAnalyzer
 20    {
 21        public static IList<FilterSpecRaw> AnalyzeFilters(StatementSpecRaw spec) {
 22            IList<FilterSpecRaw> result = new List<FilterSpecRaw>();
 23            AddFilters(spec, result);
 24    
 25            var subselects = WalkSubselectAndDeclaredDotExpr(spec);
 26            foreach (var subselect in subselects.Subselects) {
 27                AddFilters(subselect.StatementSpecRaw, result);
 28            }
 29            return result;
 30        }
 31    
 32        private static void AddFilters(StatementSpecRaw spec, IList<FilterSpecRaw> filters) {
 33            foreach (var raw in spec.StreamSpecs) {
 34                if (raw is FilterStreamSpecRaw) {
 35                    var r = (FilterStreamSpecRaw) raw;
 36                    filters.Add(r.RawFilterSpec);
 37                }
 38                if (raw is PatternStreamSpecRaw) {
 39                    var r = (PatternStreamSpecRaw) raw;
 40                    var evalNodeAnalysisResult = EvalNodeUtil.RecursiveAnalyzeChildNodes(r.EvalFactoryNode);
 41                    var filterNodes = evalNodeAnalysisResult.FilterNodes;
 42                    foreach (var filterNode in filterNodes)
 43                    {
 44                        filters.Add(filterNode.RawFilterSpec);
 45                    }
 46                }
 47            }
 48        }
 49    
 50        public static ExprNodeSubselectDeclaredDotVisitor WalkSubselectAndDeclaredDotExpr(StatementSpecRaw spec)
 51        {
 52            // Look for expressions with sub-selects in select expression list and filter expression
 53            // Recursively compile the statement within the statement.
 54            var visitor = new ExprNodeSubselectDeclaredDotVisitor();
 55            foreach (var raw in spec.SelectClauseSpec.SelectExprList)
 56            {
 57                if (raw is SelectClauseExprRawSpec)
 58                {
 59                    var rawExpr = (SelectClauseExprRawSpec) raw;
 60                    rawExpr.SelectExpression.Accept(visitor);
 61                }
 62            }
 63            if (spec.FilterRootNode != null)
 64            {
 65                spec.FilterRootNode.Accept(visitor);
 66            }
 67            if (spec.HavingExprRootNode != null)
 68            {
 69                spec.HavingExprRootNode.Accept(visitor);
 70            }
 71            if (spec.UpdateDesc != null)
 72            {
 73                if (spec.UpdateDesc.OptionalWhereClause != null)
 74                {
 75                    spec.UpdateDesc.OptionalWhereClause.Accept(visitor);
 76                }
 77                foreach (var assignment in spec.UpdateDesc.Assignments)
 78                {
 79                    assignment.Expression.Accept(visitor);
 80                }
 81            }
 82            if (spec.OnTriggerDesc != null) {
 83                VisitSubselectOnTrigger(spec.OnTriggerDesc, visitor);
 84            }
 85            // Determine pattern-filter subqueries
 86            foreach (var streamSpecRaw in spec.StreamSpecs) {
 87                if (streamSpecRaw is PatternStreamSpecRaw) {
 88                    var patternStreamSpecRaw = (PatternStreamSpecRaw) streamSpecRaw;
 89                    var analysisResult = EvalNodeUtil.RecursiveAnalyzeChildNodes(patternStreamSpecRaw.EvalFactoryNode);
 90                    foreach (var evalNode in analysisResult.ActiveNodes) {
 91                        if (evalNode is EvalFilterFactoryNode) {
 92                            var filterNode = (EvalFilterFactoryNode) evalNode;
 93                            foreach (var filterExpr in filterNode.RawFilterSpec.FilterExpressions) {
 94                                filterExpr.Accept(visitor);
 95                            }
 96                        }
 97                        else if (evalNode is EvalObserverFactoryNode) {
 98                            var beforeCount = visitor.Subselects.Count;
 99                            var observerNode = (EvalObserverFactoryNode) evalNode;
100                            foreach (var param in observerNode.PatternObserverSpec.ObjectParameters) {
101                                param.Accept(visitor);
102                            }
103                            if (visitor.Subselects.Count != beforeCount) {
104                                throw new ExprValidationException("Subselects are not allowed within pattern observer parameters, please consider using a variable instead");
105                            }
106                        }
107                    }
108                }
109            }
110            // Determine filter streams
111            foreach (var rawSpec in spec.StreamSpecs)
112            {
113                if (rawSpec is FilterStreamSpecRaw) {
114                    var raw = (FilterStreamSpecRaw) rawSpec;
115                    foreach (var filterExpr in raw.RawFilterSpec.FilterExpressions) {
116                        filterExpr.Accept(visitor);
117                    }
118                }
119            }
120    
121            return visitor;
122        }
123    
124        private static void VisitSubselectOnTrigger(OnTriggerDesc onTriggerDesc, ExprNodeSubselectDeclaredDotVisitor visitor) {
125            if (onTriggerDesc is OnTriggerWindowUpdateDesc) {
126                var updates = (OnTriggerWindowUpdateDesc) onTriggerDesc;
127                foreach (var assignment in updates.Assignments)
128                {
129                    assignment.Expression.Accept(visitor);
130                }
131            }
132            else if (onTriggerDesc is OnTriggerSetDesc) {
133                var sets = (OnTriggerSetDesc) onTriggerDesc;
134                foreach (var assignment in sets.Assignments)
135                {
136                    assignment.Expression.Accept(visitor);
137                }
138            }
139            else if (onTriggerDesc is OnTriggerSplitStreamDesc) {
140                var splits = (OnTriggerSplitStreamDesc) onTriggerDesc;
141                foreach (var split in splits.SplitStreams)
142                {
143                    if (split.WhereClause != null) {
144                        split.WhereClause.Accept(visitor);
145                    }
146                    if (split.SelectClause.SelectExprList != null) {
147                        foreach (var element in split.SelectClause.SelectExprList) {
148                            if (element is SelectClauseExprRawSpec) {
149                                var selectExpr = (SelectClauseExprRawSpec) element;
150                                selectExpr.SelectExpression.Accept(visitor);
151                            }
152                        }
153                    }
154                }
155            }
156            else if (onTriggerDesc is OnTriggerMergeDesc) {
157                var merge = (OnTriggerMergeDesc) onTriggerDesc;
158                foreach (var matched in merge.Items) {
159                    if (matched.OptionalMatchCond != null) {
160                        matched.OptionalMatchCond.Accept(visitor);
161                    }
162                    foreach (var action in matched.Actions)
163                    {
164                        if (action.OptionalWhereClause != null) {
165                            action.OptionalWhereClause.Accept(visitor);
166                        }
167    
168                        if (action is OnTriggerMergeActionUpdate) {
169                            var update = (OnTriggerMergeActionUpdate) action;
170                            foreach (var assignment in update.Assignments)
171                            {
172                                assignment.Expression.Accept(visitor);
173                            }
174                        }
175                        if (action is OnTriggerMergeActionInsert) {
176                            var insert = (OnTriggerMergeActionInsert) action;
177                            foreach (var element in insert.SelectClause) {
178                                if (element is SelectClauseExprRawSpec) {
179                                    var selectExpr = (SelectClauseExprRawSpec) element;
180                                    selectExpr.SelectExpression.Accept(visitor);
181                                }
182                            }
183                        }
184                    }
185                }
186            }
187        }
188    
189        public static IList<ExprNode> CollectExpressionsShallow(StatementSpecRaw raw) {
190            var expressions = new List<ExprNode>();
191    
192            if (raw.ExpressionDeclDesc != null) {
193                foreach (var decl in raw.ExpressionDeclDesc.Expressions) {
194                    expressions.Add(decl.Inner);
195                }
196            }
197    
198            if (raw.CreateExpressionDesc != null) {
199                if (raw.CreateExpressionDesc.Expression != null) {
200                    expressions.Add(raw.CreateExpressionDesc.Expression.Inner);
201                }
202            }
203    
204            if (raw.CreateContextDesc != null) {
205                var detail = raw.CreateContextDesc.ContextDetail;
206                if (detail is ContextDetailPartitioned) {
207                    var ks = (ContextDetailPartitioned) detail;
208                    foreach (var item in ks.Items) {
209                        if (item.FilterSpecRaw.FilterExpressions != null) {
210                            expressions.AddAll(item.FilterSpecRaw.FilterExpressions);
211                        }
212                    }
213                }
214                else if (detail is ContextDetailCategory) {
215                    var cat = (ContextDetailCategory) detail;
216                    foreach (var item in cat.Items) {
217                        if (item.Expression != null) {
218                            expressions.Add(item.Expression);
219                        }
220                    }
221                    if (cat.FilterSpecRaw.FilterExpressions != null) {
222                        expressions.AddAll(cat.FilterSpecRaw.FilterExpressions);
223                    }
224                }
225                else if (detail is ContextDetailInitiatedTerminated) {
226                    var ts = (ContextDetailInitiatedTerminated) detail;
227                    CollectExpressions(expressions, ts.Start);
228                    CollectExpressions(expressions, ts.End);
229                }
230                else {
231                    throw new EPException("Failed to obtain expressions from context detail " + detail);
232                }
233            }
234    
235            if (raw.CreateVariableDesc != null) {
236                var expr = raw.CreateVariableDesc.Assignment;
237                if (expr != null) {
238                    expressions.Add(expr);
239                }
240            }
241    
242            if (raw.CreateWindowDesc != null) {
243                var expr = raw.CreateWindowDesc.InsertFilter;
244                if (expr != null) {
245                    expressions.Add(expr);
246                }
247                foreach (var view in raw.CreateWindowDesc.ViewSpecs) {
248                    expressions.AddAll(view.ObjectParameters);
249                }
250            }
251    
252            if (raw.UpdateDesc != null) {
253                if (raw.UpdateDesc.OptionalWhereClause != null) {
254                    expressions.Add(raw.UpdateDesc.OptionalWhereClause);
255                }
256                if (raw.UpdateDesc.Assignments != null) {
257                    foreach (var pair in raw.UpdateDesc.Assignments) {
258                        expressions.Add(pair.Expression);
259                    } 
260                }
261            }
262                                
263            // on-expr
264            if (raw.OnTriggerDesc != null) {
265                if (raw.OnTriggerDesc is OnTriggerSplitStreamDesc) {
266                    var onSplit = (OnTriggerSplitStreamDesc) raw.OnTriggerDesc;
267                    foreach (var item in onSplit.SplitStreams) {
268                        if (item.SelectClause != null) {
269                            AddSelectClause(expressions, item.SelectClause.SelectExprList);
270                        }
271                        if (item.WhereClause != null) {
272                            expressions.Add(item.WhereClause);
273                        }
274                    }
275                }
276                if (raw.OnTriggerDesc is OnTriggerSetDesc) {
277                    var onSet = (OnTriggerSetDesc) raw.OnTriggerDesc;
278                    if (onSet.Assignments != null) {
279                        foreach (var aitem in onSet.Assignments) {
280                            expressions.Add(aitem.Expression);
281                        }
282                    }
283                }
284                if (raw.OnTriggerDesc is OnTriggerWindowUpdateDesc) {
285                    var onUpdate = (OnTriggerWindowUpdateDesc) raw.OnTriggerDesc;
286                    if (onUpdate.Assignments != null) {
287                        foreach (var bitem in onUpdate.Assignments) {
288                            expressions.Add(bitem.Expression);
289                        }
290                    }
291                }
292                if (raw.OnTriggerDesc is OnTriggerMergeDesc) {
293                    var onMerge = (OnTriggerMergeDesc) raw.OnTriggerDesc;
294                    foreach (var item in onMerge.Items) {
295                        if (item.OptionalMatchCond != null) {
296                            expressions.Add(item.OptionalMatchCond);
297                        }
298                        foreach (var action in item.Actions) {
299                            if (action is OnTriggerMergeActionDelete) {
300                                var delete = (OnTriggerMergeActionDelete) action;
301                                if (delete.OptionalWhereClause != null) {
302                                    expressions.Add(delete.OptionalWhereClause);
303                                }
304                            }
305                            else if (action is OnTriggerMergeActionUpdate) {
306                                var update = (OnTriggerMergeActionUpdate) action;
307                                if (update.OptionalWhereClause != null) {
308                                    expressions.Add(update.OptionalWhereClause);
309                                }
310                                foreach (var assignment in update.Assignments) {
311                                    expressions.Add(assignment.Expression);
312                                }
313                            }
314                            else if (action is OnTriggerMergeActionInsert) {
315                                var insert = (OnTriggerMergeActionInsert) action;
316                                if (insert.OptionalWhereClause != null) {
317                                    expressions.Add(insert.OptionalWhereClause);
318                                }
319                                AddSelectClause(expressions, insert.SelectClause);
320                            }
321                        }
322                    }
323                }
324            }
325            
326            // select clause
327            if (raw.SelectClauseSpec != null) {
328                AddSelectClause(expressions, raw.SelectClauseSpec.SelectExprList);
329            }
330    
331            // from clause
332            if (raw.StreamSpecs != null) {
333                foreach (var stream in raw.StreamSpecs) {
334                    // filter stream
335                    if (stream is FilterStreamSpecRaw) {
336                        var filterStream = (FilterStreamSpecRaw) stream;
337                        var filter = filterStream.RawFilterSpec;
338                        if ((filter != null) && (filter.FilterExpressions != null)){
339                            expressions.AddAll(filter.FilterExpressions);
340                        }
341                        if ((filter != null) && (filter.OptionalPropertyEvalSpec != null)) {
342                            foreach (var contained in filter.OptionalPropertyEvalSpec.Atoms) {
343                                AddSelectClause(expressions, contained.OptionalSelectClause == null ? null : contained.OptionalSelectClause.SelectExprList);
344                                if (contained.OptionalWhereClause != null) {
345                                    expressions.Add(contained.OptionalWhereClause);
346                                }
347                            }
348                        }
349                    }
350                    // pattern stream
351                    if (stream is PatternStreamSpecRaw) {
352                        var patternStream = (PatternStreamSpecRaw) stream;
353                        CollectPatternExpressions(expressions, patternStream.EvalFactoryNode);
354                    }
355                    // method stream
356                    if (stream is MethodStreamSpec) {
357                        var methodStream = (MethodStreamSpec) stream;
358                        if (methodStream.Expressions != null) {
359                            expressions.AddAll(methodStream.Expressions);
360                        }
361                    }
362                    if (stream.ViewSpecs != null) {
363                        foreach (var view in stream.ViewSpecs) {
364                            expressions.AddAll(view.ObjectParameters);
365                        }
366                    }
367                }
368    
369                if (raw.OuterJoinDescList != null) {
370                    foreach (var q in raw.OuterJoinDescList) {
371                        if (q.OptLeftNode != null) {
372                            expressions.Add(q.OptLeftNode);
373                            expressions.Add(q.OptRightNode);
374                            foreach (var ident in q.AdditionalLeftNodes) {
375                                expressions.Add(ident);
376                            }
377                            foreach (var ident in q.AdditionalRightNodes) {
378                                expressions.Add(ident);
379                            }
380                        }
381                    }
382                }
383            }
384            
385            if (raw.FilterRootNode != null) {
386                expressions.Add(raw.FilterRootNode);
387            }
388            
389            if (raw.GroupByExpressions != null) {
390                foreach (GroupByClauseElement element in raw.GroupByExpressions) {
391                    if (element is GroupByClauseElementExpr) {
392                        expressions.Add( ((GroupByClauseElementExpr) element).Expr);
393                    }
394                    else if (element is GroupByClauseElementRollupOrCube) {
395                        var rollup = (GroupByClauseElementRollupOrCube) element;
396                        AnalyzeRollup(rollup, expressions);
397                    }
398                    else {
399                        var set = (GroupByClauseElementGroupingSet) element;
400                        foreach (GroupByClauseElement inner in set.Elements) {
401                            if (inner is GroupByClauseElementExpr) {
402                                expressions.Add( ((GroupByClauseElementExpr) inner).Expr);
403                            }
404                            else if (inner is GroupByClauseElementCombinedExpr)
405                            {
406                                expressions.AddAll( ((GroupByClauseElementCombinedExpr) inner).Expressions);
407                            }
408                            else {
409                                AnalyzeRollup((GroupByClauseElementRollupOrCube) inner, expressions);
410                            }
411                        }
412                    }
413                }
414            }
415    
416            if (raw.HavingExprRootNode != null) {
417                expressions.Add(raw.HavingExprRootNode);
418            }
419    
420            if (raw.OutputLimitSpec != null) {
421                if (raw.OutputLimitSpec.WhenExpressionNode != null) {
422                    expressions.Add(raw.OutputLimitSpec.WhenExpressionNode);
423                }
424                if (raw.OutputLimitSpec.ThenExpressions != null) {
425                    foreach (var thenAssign in raw.OutputLimitSpec.ThenExpressions) {
426                        expressions.Add(thenAssign.Expression);
427                    }					
428                }
429                if (raw.OutputLimitSpec.CrontabAtSchedule != null) {
430                    expressions.AddAll(raw.OutputLimitSpec.CrontabAtSchedule);
431                }
432                if (raw.OutputLimitSpec.TimePeriodExpr != null) {
433                    expressions.Add(raw.OutputLimitSpec.TimePeriodExpr);
434                }
435                if (raw.OutputLimitSpec.AfterTimePeriodExpr != null) {
436                    expressions.Add(raw.OutputLimitSpec.AfterTimePeriodExpr);
437                }
438            }
439            
440            if (raw.OrderByList != null) {
441                foreach (var orderByElement in raw.OrderByList) {
442                    expressions.Add(orderByElement.ExprNode);
443                }									
444            }
445            
446            if (raw.MatchRecognizeSpec != null) {
447                if (raw.MatchRecognizeSpec.PartitionByExpressions != null) {
448                    expressions.AddAll(raw.MatchRecognizeSpec.PartitionByExpressions);
449                }
450                foreach (var selectItemMR in raw.MatchRecognizeSpec.Measures) {
451                    expressions.Add(selectItemMR.Expr);
452                }
453                foreach (var define in raw.MatchRecognizeSpec.Defines) {
454                    expressions.Add(define.Expression);
455                }
456                if (raw.MatchRecognizeSpec.Interval != null) {
457                    if (raw.MatchRecognizeSpec.Interval.TimePeriodExpr != null) {
458                        expressions.Add(raw.MatchRecognizeSpec.Interval.TimePeriodExpr);
459                    }
460                }
461            }
462    
463            if (raw.ForClauseSpec != null) {
464                foreach (var item in raw.ForClauseSpec.Clauses) {
465                    if (item.Expressions != null) {
466                        expressions.AddAll(item.Expressions);
467                    }
468                }
469            }
470    
471            return expressions;
472        }
473    
474        private static void AnalyzeRollup(GroupByClauseElementRollupOrCube rollup, List<ExprNode> expressions) {
475            foreach (GroupByClauseElement ex in rollup.RollupExpressions) {
476                if (ex is GroupByClauseElementExpr) {
477                    expressions.Add( ((GroupByClauseElementExpr) ex).Expr);
478                }
479                else {
480                    var combined = (GroupByClauseElementCombinedExpr) ex;
481                    expressions.AddAll(combined.Expressions);
482                }
483            }
484        }
485
486        private static void CollectExpressions(IList<ExprNode> expressions, ContextDetailCondition endpoint) {
487            if (endpoint is ContextDetailConditionCrontab) {
488                var crontab = (ContextDetailConditionCrontab) endpoint;
489                expressions.AddAll(crontab.Crontab);
490            }
491        }
492    
493        private static void AddSelectClause(IList<ExprNode> expressions, IList<SelectClauseElementRaw> selectClause) {
494            if (selectClause == null) {
495                return;
496            }
497            foreach (var selement in selectClause) {
498                if (!(selement is SelectClauseExprRawSpec)) {
499                    continue;
500                }
501                var sexpr = (SelectClauseExprRawSpec) selement;
502                expressions.Add(sexpr.SelectExpression);
503            }
504        }
505    
506        private static void CollectPatternExpressions(IList<ExprNode> expressions, EvalFactoryNode patternExpression) {
507    
508            if (patternExpression is EvalFilterFactoryNode) {
509                var filter = (EvalFilterFactoryNode) patternExpression;
510                if (filter.RawFilterSpec.FilterExpressions != null) {
511                    expressions.AddAll(filter.RawFilterSpec.FilterExpressions);
512                }
513            }
514    
515            foreach (var child in patternExpression.ChildNodes) {
516                CollectPatternExpressions(expressions, child);
517            }
518        }
519    }
520}