PageRenderTime 63ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

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