1 //---------------------------------------------------------------------
2 // <copyright file="QueryExpr.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //---------------------------------------------------------------------
10 namespace System.Data.Common.EntitySql.AST
13 using System.Globalization;
14 using System.Collections;
15 using System.Collections.Generic;
18 /// Represents select kind (value,row).
20 internal enum SelectKind
27 /// Represents join kind (cross,inner,leftouter,rightouter).
29 internal enum JoinKind
39 /// Represents order kind (none=asc,asc,desc).
41 internal enum OrderKind
49 /// Represents distinct kind (none=all,all,distinct).
51 internal enum DistinctKind
59 /// Represents apply kind (cross,outer).
61 internal enum ApplyKind
68 /// Represents a query expression ast node.
70 internal sealed class QueryExpr : Node
72 private readonly SelectClause _selectClause;
73 private readonly FromClause _fromClause;
74 private readonly Node _whereClause;
75 private readonly GroupByClause _groupByClause;
76 private readonly HavingClause _havingClause;
77 private readonly OrderByClause _orderByClause;
80 /// Initializes a query expression ast node.
82 /// <param name="selectClause">select clause</param>
83 /// <param name="fromClause">from clasuse</param>
84 /// <param name="whereClause">optional where clause</param>
85 /// <param name="groupByClause">optional group by clause</param>
86 /// <param name="havingClause">optional having clause</param>
87 /// <param name="orderByClause">optional order by clause</param>
88 internal QueryExpr(SelectClause selectClause,
89 FromClause fromClause,
91 GroupByClause groupByClause,
92 HavingClause havingClause,
93 OrderByClause orderByClause)
95 _selectClause = selectClause;
96 _fromClause = fromClause;
97 _whereClause = whereClause;
98 _groupByClause = groupByClause;
99 _havingClause = havingClause;
100 _orderByClause = orderByClause;
104 /// Returns select clause.
106 internal SelectClause SelectClause
108 get { return _selectClause; }
112 /// Returns from clause.
114 internal FromClause FromClause
116 get { return _fromClause; }
120 /// Returns optional where clause (expr).
122 internal Node WhereClause
124 get { return _whereClause; }
128 /// Returns optional group by clause.
130 internal GroupByClause GroupByClause
132 get { return _groupByClause; }
136 /// Returns optional having clause (expr).
138 internal HavingClause HavingClause
140 get { return _havingClause; }
144 /// Returns optional order by clause.
146 internal OrderByClause OrderByClause
148 get { return _orderByClause; }
152 /// Returns true if method calls are present.
154 internal bool HasMethodCall
158 return _selectClause.HasMethodCall ||
159 (null != _havingClause && _havingClause.HasMethodCall) ||
160 (null != _orderByClause && _orderByClause.HasMethodCall);
166 /// Represents select clause.
168 internal sealed class SelectClause : Node
170 private readonly NodeList<AliasedExpr> _selectClauseItems;
171 private readonly SelectKind _selectKind;
172 private readonly DistinctKind _distinctKind;
173 private readonly Node _topExpr;
174 private readonly uint _methodCallCount;
177 /// Initialize SelectKind.SelectRow clause.
179 internal SelectClause(NodeList<AliasedExpr> items, SelectKind selectKind, DistinctKind distinctKind, Node topExpr, uint methodCallCount)
181 _selectKind = selectKind;
182 _selectClauseItems = items;
183 _distinctKind = distinctKind;
185 _methodCallCount = methodCallCount;
191 internal NodeList<AliasedExpr> Items
193 get { return _selectClauseItems; }
197 /// Select kind (row or value).
199 internal SelectKind SelectKind
201 get { return _selectKind; }
205 /// Distinct kind (none,all,distinct).
207 internal DistinctKind DistinctKind
209 get { return _distinctKind; }
213 /// Optional top expression.
215 internal Node TopExpr
217 get { return _topExpr; }
221 /// True if select list has method calls.
223 internal bool HasMethodCall
225 get { return (_methodCallCount > 0); }
230 /// Represents from clause.
232 internal sealed class FromClause : Node
234 private readonly NodeList<FromClauseItem> _fromClauseItems;
237 /// Initializes from clause.
239 internal FromClause(NodeList<FromClauseItem> fromClauseItems)
241 _fromClauseItems = fromClauseItems;
245 /// List of from clause items.
247 internal NodeList<FromClauseItem> FromClauseItems
249 get { return _fromClauseItems; }
254 /// From clause item kind.
256 internal enum FromClauseItemKind
264 /// Represents single from clause item.
266 internal sealed class FromClauseItem : Node
268 private readonly Node _fromClauseItemExpr;
269 private readonly FromClauseItemKind _fromClauseItemKind;
272 /// Initializes as 'simple' aliased expression.
274 internal FromClauseItem(AliasedExpr aliasExpr)
276 _fromClauseItemExpr = aliasExpr;
277 _fromClauseItemKind = FromClauseItemKind.AliasedFromClause;
281 /// Initializes as join clause item.
283 internal FromClauseItem(JoinClauseItem joinClauseItem)
285 _fromClauseItemExpr = joinClauseItem;
286 _fromClauseItemKind = FromClauseItemKind.JoinFromClause;
290 /// Initializes as apply clause item.
292 internal FromClauseItem(ApplyClauseItem applyClauseItem)
294 _fromClauseItemExpr = applyClauseItem;
295 _fromClauseItemKind = FromClauseItemKind.ApplyFromClause;
299 /// From clause item expression.
301 internal Node FromExpr
303 get { return _fromClauseItemExpr; }
307 /// From clause item kind (alias,join,apply).
309 internal FromClauseItemKind FromClauseItemKind
311 get { return _fromClauseItemKind; }
316 /// Represents group by clause.
318 internal sealed class GroupByClause : Node
320 private readonly NodeList<AliasedExpr> _groupItems;
323 /// Initializes GROUP BY clause
325 internal GroupByClause(NodeList<AliasedExpr> groupItems)
327 _groupItems = groupItems;
333 internal NodeList<AliasedExpr> GroupItems
335 get { return _groupItems; }
340 /// Represents having clause.
342 internal sealed class HavingClause : Node
344 private readonly Node _havingExpr;
345 private readonly uint _methodCallCount;
348 /// Initializes having clause.
350 internal HavingClause(Node havingExpr, uint methodCallCounter)
352 _havingExpr = havingExpr;
353 _methodCallCount = methodCallCounter;
357 /// Returns having inner expression.
359 internal Node HavingPredicate
361 get { return _havingExpr; }
365 /// True if predicate has method calls.
367 internal bool HasMethodCall
369 get { return (_methodCallCount > 0); }
374 /// Represents order by clause.
376 internal sealed class OrderByClause : Node
378 private readonly NodeList<OrderByClauseItem> _orderByClauseItem;
379 private readonly Node _skipExpr;
380 private readonly Node _limitExpr;
381 private readonly uint _methodCallCount;
384 /// Initializes order by clause.
386 internal OrderByClause(NodeList<OrderByClauseItem> orderByClauseItem, Node skipExpr, Node limitExpr, uint methodCallCount)
388 _orderByClauseItem = orderByClauseItem;
389 _skipExpr = skipExpr;
390 _limitExpr = limitExpr;
391 _methodCallCount = methodCallCount;
395 /// Returns order by clause items.
397 internal NodeList<OrderByClauseItem> OrderByClauseItem
399 get { return _orderByClauseItem; }
403 /// Returns skip sub clause ast node.
405 internal Node SkipSubClause
407 get { return _skipExpr; }
411 /// Returns limit sub-clause ast node.
413 internal Node LimitSubClause
415 get { return _limitExpr; }
419 /// True if order by has method calls.
421 internal bool HasMethodCall
423 get { return (_methodCallCount > 0); }
428 /// Represents a order by clause item.
430 internal sealed class OrderByClauseItem : Node
432 private readonly Node _orderExpr;
433 private readonly OrderKind _orderKind;
434 private readonly Identifier _optCollationIdentifier;
437 /// Initializes non-collated order by clause item.
439 internal OrderByClauseItem(Node orderExpr, OrderKind orderKind)
440 : this(orderExpr, orderKind, null)
445 /// Initializes collated order by clause item.
447 /// <param name="optCollationIdentifier">optional Collation identifier</param>
448 internal OrderByClauseItem(Node orderExpr, OrderKind orderKind, Identifier optCollationIdentifier)
450 _orderExpr = orderExpr;
451 _orderKind = orderKind;
452 _optCollationIdentifier = optCollationIdentifier;
456 /// Oeturns order expression.
458 internal Node OrderExpr
460 get { return _orderExpr; }
464 /// Returns order kind (none,asc,desc).
466 internal OrderKind OrderKind
468 get { return _orderKind; }
472 /// Returns collattion identifier if one exists.
474 internal Identifier Collation
476 get { return _optCollationIdentifier; }
481 /// Represents join clause item.
483 internal sealed class JoinClauseItem : Node
485 private readonly FromClauseItem _joinLeft;
486 private readonly FromClauseItem _joinRight;
487 private JoinKind _joinKind;
488 private readonly Node _onExpr;
491 /// Initializes join clause item without ON expression.
493 internal JoinClauseItem(FromClauseItem joinLeft, FromClauseItem joinRight, JoinKind joinKind)
494 : this(joinLeft, joinRight, joinKind, null)
499 /// Initializes join clause item with ON expression.
501 internal JoinClauseItem(FromClauseItem joinLeft, FromClauseItem joinRight, JoinKind joinKind, Node onExpr)
503 _joinLeft = joinLeft;
504 _joinRight = joinRight;
505 _joinKind = joinKind;
510 /// Returns join left expression.
512 internal FromClauseItem LeftExpr
514 get { return _joinLeft; }
518 /// Returns join right expression.
520 internal FromClauseItem RightExpr
522 get { return _joinRight; }
526 /// Join kind (cross, inner, full, left outer,right outer).
528 internal JoinKind JoinKind
530 get { return _joinKind; }
531 set { _joinKind = value; }
535 /// Returns join on expression.
539 get { return _onExpr; }
544 /// Represents apply expression.
546 internal sealed class ApplyClauseItem : Node
548 private readonly FromClauseItem _applyLeft;
549 private readonly FromClauseItem _applyRight;
550 private readonly ApplyKind _applyKind;
553 /// Initializes apply clause item.
555 internal ApplyClauseItem(FromClauseItem applyLeft, FromClauseItem applyRight, ApplyKind applyKind)
557 _applyLeft = applyLeft;
558 _applyRight = applyRight;
559 _applyKind = applyKind;
563 /// Returns apply left expression.
565 internal FromClauseItem LeftExpr
567 get { return _applyLeft; }
571 /// Returns apply right expression.
573 internal FromClauseItem RightExpr
575 get { return _applyRight; }
579 /// Returns apply kind (cross,outer).
581 internal ApplyKind ApplyKind
583 get { return _applyKind; }