Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

726 lines
22 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. WQLNODE.H
  5. Abstract:
  6. WQL Parse Node Definitions
  7. History:
  8. raymcc 29-Sep-97 Created
  9. --*/
  10. #ifndef _WQLNODE_H_
  11. #define _WQLNODE_H_
  12. #define WQL_FLAG_ALIAS 0x1
  13. #define WQL_FLAG_TABLE 0x2
  14. #define WQL_FLAG_ASTERISK 0x4
  15. #define WQL_FLAG_DISTINCT 0x8
  16. #define WQL_FLAG_ALL 0x10
  17. #define WQL_FLAG_COUNT 0x20
  18. #define WQL_FLAG_CONST 0x40
  19. #define WQL_FLAG_COLUMN 0x80
  20. #define WQL_FLAG_COMPLEX_NAME 0x100
  21. #define WQL_FLAG_FUNCTIONIZED 0x200
  22. #define WQL_FLAG_ARRAY_REF 0x400
  23. #define WQL_FLAG_UPPER 0x800
  24. #define WQL_FLAG_LOWER 0x1000
  25. #define WQL_FLAG_FIRSTROW 0x2000
  26. #define WQL_FLAG_CONST_RANGE 0x4000
  27. #define WQL_FLAG_SORT_ASC 0x8000
  28. #define WQL_FLAG_SORT_DESC 0x10000
  29. #define WQL_FLAG_AGGREGATE 0x20000
  30. #define WQL_FLAG_NULL 0x40000
  31. #define WQL_FLAG_INNER_JOIN 1
  32. #define WQL_FLAG_LEFT_OUTER_JOIN 2
  33. #define WQL_FLAG_RIGHT_OUTER_JOIN 3
  34. #define WQL_FLAG_FULL_OUTER_JOIN 4
  35. //***************************************************************************
  36. //
  37. // SWQLNode
  38. //
  39. // Base node type for all parser output.
  40. //
  41. //***************************************************************************
  42. struct SWQLNode
  43. {
  44. DWORD m_dwNodeType;
  45. SWQLNode *m_pLeft;
  46. SWQLNode *m_pRight;
  47. SWQLNode() { m_pLeft = 0; m_pRight = 0; m_dwNodeType = 0; }
  48. virtual ~SWQLNode() { delete m_pLeft; delete m_pRight; }
  49. virtual void DebugDump() = 0;
  50. };
  51. //***************************************************************************
  52. //
  53. // SWQLTypedConst
  54. //
  55. // Typed constant container (similar to OA VARIANT).
  56. //
  57. //***************************************************************************
  58. union UWQLTypedConst
  59. {
  60. LPWSTR m_pString; // VT_LPWSTR for WQL_TOK_QSTRING and WQL_TOK_PROMPT
  61. LONG m_lValue; // VT_LONG
  62. double m_dblValue; // VT_DOUBLE
  63. BOOL m_bValue; // VT_BOOL, use TRUE/FALSE (not VARIANT_TRUE, VARIANT_FALSE)
  64. };
  65. struct SWQLTypedConst
  66. {
  67. DWORD m_dwType; // A VT_ type
  68. UWQLTypedConst m_Value; // One of the union fields
  69. bool m_bPrompt; // Only true if token was WQL_TOK_PROMPT
  70. SWQLTypedConst();
  71. SWQLTypedConst(SWQLTypedConst &Src) { m_dwType = VT_NULL; *this = Src; }
  72. SWQLTypedConst & operator = (SWQLTypedConst &Src);
  73. ~SWQLTypedConst() { Empty(); }
  74. void Empty();
  75. void DebugDump();
  76. };
  77. struct SWQLConstList
  78. {
  79. CFlexArray m_aValues; // ptrs to SWQLTypedConst
  80. SWQLConstList() {}
  81. SWQLConstList(SWQLConstList &Src) { *this = Src; }
  82. SWQLConstList & operator = (SWQLConstList & Src);
  83. ~SWQLConstList() { Empty(); }
  84. void Add(SWQLTypedConst *pTC) { m_aValues.Add(pTC); }
  85. void Empty();
  86. };
  87. struct SWQLQualifiedNameField
  88. {
  89. LPWSTR m_pName; // Name
  90. BOOL m_bArrayRef; // TRUE if this is an array reference
  91. DWORD m_dwArrayIndex; // If <m_bArrayRef == TRUE> this is the array index
  92. SWQLQualifiedNameField() { m_pName = 0; m_bArrayRef = 0; m_dwArrayIndex = 0; }
  93. SWQLQualifiedNameField(SWQLQualifiedNameField &Src) { m_pName = 0; *this = Src; }
  94. SWQLQualifiedNameField & operator = (SWQLQualifiedNameField &Src);
  95. ~SWQLQualifiedNameField() { Empty(); }
  96. void Empty() { delete [] m_pName; }
  97. };
  98. struct SWQLQualifiedName
  99. {
  100. CFlexArray m_aFields; // [0] = left most, last entry is column
  101. SWQLQualifiedName() {}
  102. SWQLQualifiedName(SWQLQualifiedName &Src) { *this = Src; }
  103. SWQLQualifiedName & operator = (SWQLQualifiedName &Src);
  104. ~SWQLQualifiedName() { Empty(); }
  105. int GetNumNames() { return m_aFields.Size(); }
  106. const LPWSTR GetName(int nIndex)
  107. {
  108. return (LPWSTR) ((SWQLQualifiedNameField*) m_aFields[nIndex])->m_pName;
  109. }
  110. int Add(SWQLQualifiedNameField *pQN) { return m_aFields.Add(pQN); }
  111. void Empty();
  112. };
  113. #define WQL_TOK_BASE 100
  114. //***************************************************************************
  115. //
  116. // SWQLNode_Select
  117. //
  118. // This is the root of the parse tree or the root of a subselect.
  119. //
  120. // SWQLNode_Select
  121. // / \
  122. // SWQLNode_TableRefs SWQLNode_WhereClause
  123. // / \ / \
  124. // x x x x
  125. //
  126. //***************************************************************************
  127. #define TYPE_SWQLNode_Select (WQL_TOK_BASE + 1)
  128. struct SWQLNode_Select : SWQLNode
  129. {
  130. // Left Node is of type SWQLNode_TableRefs
  131. // Right Node is of type SWQLNode_WhereClause
  132. int m_nStPos;
  133. int m_nEndPos;
  134. SWQLNode_Select() : m_nStPos(-1), m_nEndPos(-1) { m_dwNodeType = TYPE_SWQLNode_Select; }
  135. void DebugDump();
  136. };
  137. //***************************************************************************
  138. //
  139. // SWQLNode_TableRefs
  140. //
  141. // This contains everything prior to the WHERE clause: the target
  142. // column list and the FROM clause.
  143. //
  144. // Also contains the SELECT type, i.e., ALL vs. DISTINCT vs. COUNT.
  145. //
  146. // SWQLNode_TableRefs
  147. // / \
  148. // SWQLNode_ColumnList SWQLNode_FromClause
  149. //
  150. // In all cases, SWQLNode_ColumnList is present. Note that if the
  151. // user did a "select *...", then the SWQLNode_ColumnList will only
  152. // have a single column in it clearly marked as an asterisk. If
  153. // a "select count(...) " was done, then m_nSelectType is set to
  154. // WQL_FLAG_COUNT and the SWQLNode_ColumnList will have a single
  155. // column in it, whether an * or a qualified name.
  156. //
  157. //***************************************************************************
  158. #define TYPE_SWQLNode_TableRefs (WQL_TOK_BASE + 2)
  159. struct SWQLNode_TableRefs : SWQLNode
  160. {
  161. // Left Node is SWQLNode_ColumnList
  162. // Right Node is SWQLNode_FromClause
  163. int m_nSelectType; // WQL_FLAG_ALL means ALL was used.
  164. // WQL_FLAG_DISTINCT means DISTINCT was used.
  165. // WQL_FLAG_COUNT means COUNT was used.
  166. SWQLNode_TableRefs()
  167. { m_nSelectType = WQL_FLAG_ALL;
  168. m_dwNodeType = TYPE_SWQLNode_TableRefs;
  169. }
  170. ~SWQLNode_TableRefs() {}
  171. void DebugDump();
  172. };
  173. //***************************************************************************
  174. //
  175. // SWQLNode_ColumnList
  176. //
  177. // This contains the selected list of columns.
  178. //
  179. // SWQLNode_ColumnList
  180. // / \
  181. // NULL NULL
  182. //
  183. //***************************************************************************
  184. #define TYPE_SWQLNode_ColumnList (WQL_TOK_BASE + 3)
  185. struct SWQLNode_ColumnList : SWQLNode
  186. {
  187. // Left Node is NULL
  188. // Right Node is NULL
  189. CFlexArray m_aColumnRefs ; // Pointers to SWQLColRef entries.
  190. SWQLNode_ColumnList() { m_dwNodeType = TYPE_SWQLNode_ColumnList; }
  191. ~SWQLNode_ColumnList() { Empty(); }
  192. void Empty();
  193. void DebugDump();
  194. };
  195. struct SWQLColRef
  196. {
  197. LPWSTR m_pColName; // The column name or "*" or NULL
  198. LPWSTR m_pTableRef; // The table/alias name or NULL if there is none
  199. DWORD m_dwArrayIndex;
  200. DWORD m_dwFlags; // WQL_FLAG_TABLE bit set if m_pTableRef
  201. // is a table name
  202. // WQL_FLAG_ALIAS bit set if m_pTableRef
  203. // is a table alias
  204. // WQL_FLAG_ASTERISK bit set if m_pColName is
  205. // * (this is faster than to check than a
  206. // string compare on <m_pColName> for "*".
  207. // WQL_FLAG_NULL if the column name was "NULL"
  208. // WQL_FLAG_FUNCTIONIZED is set if the column
  209. // is wrapped in a function call.
  210. // The function bits WQL_FLAG_UPPER or
  211. // WQL_FLAG_LOWER will be set.
  212. // WQL_FLAG_ARRAY_REF is set if the column
  213. // is an array column, in which case
  214. // m_dwArrayIndex is set to the array offset.
  215. // WQL_FLAG_COMPLEX_NAME is set if the name
  216. // is qualified in a deeply nested way,
  217. // which requires examination of the <QName>
  218. // object. In this case <m_pColName> is
  219. // set to the last name, but m_pTableRef
  220. // is left blank.
  221. // WQL_FLAG_SORT_ASC to sort ascending (Order by only)
  222. // WQL_FLAG_SORT_DESC to sort descending (Order by only)
  223. SWQLQualifiedName *m_pQName; // The full qualified name
  224. SWQLColRef() { m_pColName = NULL; m_pTableRef = 0;
  225. m_dwFlags = 0; m_dwArrayIndex = 0; m_pQName = 0;
  226. }
  227. ~SWQLColRef() { delete [] m_pColName; delete [] m_pTableRef; delete m_pQName; }
  228. void DebugDump();
  229. };
  230. //***************************************************************************
  231. //
  232. // SWQLNode_FromClause
  233. //
  234. // The subtree containing the tables selected from and any joins.
  235. //
  236. // SWQLNode_FromClause
  237. // / \
  238. // SWQLNode_TableRef NULL
  239. // or SWQLNode_Join
  240. // or SWQLNode_Sql89Join
  241. //
  242. //***************************************************************************
  243. #define TYPE_SWQLNode_FromClause (WQL_TOK_BASE + 4)
  244. struct SWQLNode_FromClause : SWQLNode
  245. {
  246. // Left is SWQLNode_TableRef or SWQLNode_Join
  247. // Right is NULL
  248. SWQLNode_FromClause() { m_dwNodeType = TYPE_SWQLNode_FromClause; }
  249. ~SWQLNode_FromClause() {}
  250. void DebugDump();
  251. };
  252. //***************************************************************************
  253. //
  254. // SWQLNode_Sql89Join
  255. //
  256. // A subtree which expresses a SQL-89 join.
  257. //
  258. // SWQLNode_Sql89Join
  259. // / \
  260. // NULL NULL
  261. //
  262. //***************************************************************************
  263. #define TYPE_SWQLNode_Sql89Join (WQL_TOK_BASE + 5)
  264. struct SWQLNode_Sql89Join : SWQLNode
  265. {
  266. CFlexArray m_aValues; // Array of pointers to SWQLNode_TableRef
  267. // objects
  268. SWQLNode_Sql89Join() { m_dwNodeType = TYPE_SWQLNode_Sql89Join; }
  269. ~SWQLNode_Sql89Join() {Empty();};
  270. void DebugDump();
  271. void Empty();
  272. };
  273. //***************************************************************************
  274. //
  275. // SWQLNode_Join
  276. //
  277. // A subtree which expresses a join.
  278. //
  279. // SWQLNode_Join
  280. // / \
  281. // SWQLNode_JoinPair SWQLNode_OnClause or NULL.
  282. //
  283. //***************************************************************************
  284. #define TYPE_SWQLNode_Join (WQL_TOK_BASE + 6)
  285. struct SWQLNode_Join : SWQLNode
  286. {
  287. // Left ptr is SWQLNode_JoinPair
  288. // Right ptr is ON clause. If NULL, there is no ON clause
  289. // and the JOIN was a SQL-89 style join with the join condition
  290. // present in the WHERE clause.
  291. DWORD m_dwJoinType;
  292. // One of WQL_FLAG_INNER_JOIN, WQL_FLAG_LEFT_OUTER_JOIN,
  293. // WQL_FLAG_RIGHT_OUTER_JOIN or WQL_FLAG_FULL_OUTER_JOIN
  294. DWORD m_dwFlags;
  295. // Contains WQL_FLAG_FIRSTROW if used
  296. SWQLNode_Join() { m_dwNodeType = TYPE_SWQLNode_Join; m_dwJoinType = m_dwFlags = 0; }
  297. ~SWQLNode_Join() {}
  298. void DebugDump();
  299. };
  300. //***************************************************************************
  301. //
  302. // SWQLNode_JoinPair
  303. //
  304. // SWQLNode_JoinPair
  305. // / \
  306. // <SWQLNode_Join or SWQLNode_TableRef>
  307. //
  308. //***************************************************************************
  309. #define TYPE_SWQLNode_JoinPair (WQL_TOK_BASE + 7)
  310. struct SWQLNode_JoinPair : SWQLNode
  311. {
  312. // Left ptr is SWQLNode_Join or SWQLNode_TableRef
  313. // Right ptr is SWQLNodeNode_Join or SWQL_NodeTableRef
  314. SWQLNode_JoinPair() { m_dwNodeType = TYPE_SWQLNode_JoinPair; }
  315. ~SWQLNode_JoinPair() {}
  316. void DebugDump();
  317. };
  318. //***************************************************************************
  319. //
  320. // SWQLNode_TableRef
  321. //
  322. // A node representing a table name and its alias, if any.
  323. //
  324. // SWQLNode_TableRef
  325. // / \
  326. // NULL NULL
  327. //
  328. //***************************************************************************
  329. #define TYPE_SWQLNode_TableRef (WQL_TOK_BASE + 8)
  330. struct SWQLNode_TableRef : SWQLNode
  331. {
  332. LPWSTR m_pTableName; // The table
  333. LPWSTR m_pAlias; // Table alias. NULL if not used.
  334. SWQLNode_TableRef() { m_pTableName = 0; m_pAlias = 0; m_dwNodeType = TYPE_SWQLNode_TableRef; }
  335. ~SWQLNode_TableRef() { delete [] m_pTableName; delete [] m_pAlias; }
  336. void DebugDump();
  337. };
  338. //***************************************************************************
  339. //
  340. // SWQLNode_OnClause
  341. //
  342. // SWQLNode_OnClause
  343. // / \
  344. // <SWQLNode_RelExpr> NULL
  345. //
  346. //***************************************************************************
  347. #define TYPE_SWQLNode_OnClause (WQL_TOK_BASE + 9)
  348. struct SWQLNode_OnClause : SWQLNode
  349. {
  350. // Left ptr is <SWQLNode_RelExpr> which contains the ON clause.
  351. // Right ptr is always NULL.
  352. SWQLNode_OnClause() { m_dwNodeType = TYPE_SWQLNode_OnClause; }
  353. ~SWQLNode_OnClause() {}
  354. void DebugDump();
  355. };
  356. //***************************************************************************
  357. //
  358. // SWQLNode_WhereClause
  359. //
  360. // SWQLNode_WhereClause
  361. // / \
  362. // SWQLNode_RelExpr SWQLNode_WhereOptions or NULL
  363. // or
  364. // NULL if no conditions
  365. //
  366. //***************************************************************************
  367. #define TYPE_SWQLNode_WhereClause (WQL_TOK_BASE + 10)
  368. struct SWQLNode_WhereClause : SWQLNode
  369. {
  370. // Left ptr is SWQLNode_RelExpr.
  371. // Right ptr is SQLNode_QueryOptions or NULL if none
  372. SWQLNode_WhereClause() { m_dwNodeType = TYPE_SWQLNode_WhereClause; }
  373. ~SWQLNode_WhereClause() {}
  374. void DebugDump();
  375. };
  376. //***************************************************************************
  377. //
  378. // struct SWQLTypedExpr
  379. //
  380. // This represents a typed subexpression in a where clause:
  381. //
  382. // mycol < 2
  383. // 33 <= tbl1.col2
  384. // tbl3.col4 = tbl4.col5
  385. // ...etc.
  386. //
  387. //***************************************************************************
  388. struct SWQLTypedExpr
  389. {
  390. LPWSTR m_pTableRef; // For qualified column names,
  391. // NULL if not used
  392. LPWSTR m_pColRef; // Column name
  393. DWORD m_dwRelOperator; // The operator used: WQL_TOK_LE,
  394. // WQL_TOK_GE, WQL_TOK_LIKE etc.
  395. // WQL_TOK_IN_CONST_LIST
  396. // WQL_TOK_NOT_IN_CONST_LIST
  397. // WQL_TOK_IN_SUBSELECT
  398. // WQL_TOK_NOT_IN_SUBSELECT
  399. SWQLTypedConst *m_pConstValue; // A const value
  400. SWQLTypedConst *m_pConstValue2; // The other const value used with BETWEEN
  401. LPWSTR m_pJoinTableRef; // The joined table name or its alias,
  402. // NULL if not used
  403. LPWSTR m_pJoinColRef; // The joined column name
  404. LPWSTR m_pIntrinsicFuncOnColRef;
  405. LPWSTR m_pIntrinsicFuncOnJoinColRef;
  406. LPWSTR m_pIntrinsicFuncOnConstValue;
  407. SWQLNode *m_pLeftFunction; // More detail for DATEPART, etc.
  408. SWQLNode *m_pRightFunction; // More detail for DATEPART, etc.
  409. DWORD m_dwLeftArrayIndex;
  410. DWORD m_dwRightArrayIndex;
  411. SWQLQualifiedName *m_pQNRight;
  412. SWQLQualifiedName *m_pQNLeft;
  413. DWORD m_dwLeftFlags;
  414. DWORD m_dwRightFlags;
  415. // Each of the above to Flags shows the expression layout on each side
  416. // of the operator.
  417. // WQL_FLAG_CONST = A typed constant was used
  418. // WQL_FLAG_COLUMN = Column field was used
  419. // WQL_FLAG_TABLE = Table/Alias was used
  420. // WQL_FLAG_COMPLEX = Complex qualified name and/or array was used
  421. // WQL_FLAG_FUNCTIONIZED = Function was applied over the const or col.
  422. // For IN and NOT IN clauses.
  423. // ==========================
  424. SWQLNode *m_pSubSelect;
  425. SWQLConstList *m_pConstList; // For IN clause with constant-list
  426. /*
  427. (1) If a const is tested against a column, then <m_pConstValue> will
  428. be used to represent it, and the table+col referenced will be in
  429. <m_pTableRef> and <m_pColRef>.
  430. (2) If a join occurs, then <m_pConstValue> will be NULL.
  431. (3) Intrinsic functions (primarily UPPER() and LOWER()) can be applied
  432. to the column references or the constant. The function names will
  433. be placed in the <m_pIntrinsic...> pointers when applied.
  434. (4) If <m_dwRelOperator> is WQL_TOK_IN_CONST_LIST or WQL_TOK_NOT_IN_CONST_LIST
  435. then <m_aConstSet> is an array of pointers to SWQLTypedConst structs representing
  436. the set of constants that the referenced column must intersect with.
  437. (5) If <m_dwRelOperator> is WQL_TOK_IN_SUBSELECT or WQL_TOK_NOT_IN_SUBSELECT
  438. then m_pSubSelect is a pointer to an embedded subselect tree in the form
  439. of a SWQLNode_Select struct, beginning the root of an entirely new select
  440. statement.
  441. */
  442. SWQLTypedExpr();
  443. ~SWQLTypedExpr() { Empty(); }
  444. void DebugDump();
  445. void Empty();
  446. };
  447. //***************************************************************************
  448. //
  449. // SWQLNode_RelExpr
  450. //
  451. // SWQLNode_RelExpr
  452. // / \
  453. // SWQLNode_RelExpr SWQLNode_RelExpr
  454. // or NULL or NULL
  455. //
  456. //***************************************************************************
  457. #define TYPE_SWQLNode_RelExpr (WQL_TOK_BASE + 11)
  458. struct SWQLNode_RelExpr : SWQLNode
  459. {
  460. DWORD m_dwExprType; // WQL_TOK_OR
  461. // WQL_TOK_AND
  462. // WQL_TOK_NOT
  463. // WQL_TOK_TYPED_EXPR
  464. SWQLTypedExpr *m_pTypedExpr;
  465. /*
  466. (1) If the <m_dwExprType> is WQL_TOK_AND or WQL_TOK_OR, then each of
  467. the two subnodes are themselves SWQLNode_RelExpr nodes and
  468. <m_pTypedExpr> points to NULL.
  469. (2) If <m_dwExprType> is WQL_TOK_NOT, then <m_pLeft> points to a
  470. SWQLNode_RelExpr containing the subclause to which to apply the NOT
  471. operation and <m_pRight> points to NULL.
  472. (3) If <m_dwExprType> is WQL_TOK_TYPED_EXPR, then <m_pLeft> and
  473. <m_pRight> both point to NULL, and <m_pTypedExpr> contains a typed
  474. relational subexpression.
  475. (4) Parentheses have been removed and are implied by the nesting.
  476. */
  477. SWQLNode_RelExpr() { m_dwNodeType = TYPE_SWQLNode_RelExpr; m_pTypedExpr = 0; m_dwExprType = 0; }
  478. ~SWQLNode_RelExpr() { delete m_pTypedExpr; }
  479. void DebugDump();
  480. };
  481. //***************************************************************************
  482. //
  483. // SWQLNode_WhereOptions
  484. //
  485. // SWQLNode_WhereOptions
  486. // / \
  487. // SWQLNode_GroupBy SWQLNode_OrderBy
  488. //
  489. //***************************************************************************
  490. #define TYPE_SWQLNode_WhereOptions (WQL_TOK_BASE + 12)
  491. struct SWQLNode_WhereOptions : SWQLNode
  492. {
  493. // left ptr is SWQLNode_GroupBy, or NULL if not used
  494. // right ptr is SWQLNode_OrderBy, or NULL if not used
  495. SWQLNode_WhereOptions() { m_dwNodeType = TYPE_SWQLNode_WhereOptions; }
  496. void DebugDump();
  497. };
  498. //***************************************************************************
  499. //
  500. // SWQLNode_GroupBy
  501. //
  502. // SWQLNode_GroupBy
  503. // / \
  504. // SWQLNode_ColumnList SWQLNode_Having
  505. // or NULL
  506. //
  507. //***************************************************************************
  508. #define TYPE_SWQLNode_GroupBy (WQL_TOK_BASE + 13)
  509. struct SWQLNode_GroupBy : SWQLNode
  510. {
  511. // left ptr is SWQLNode_ColumnList of columns to group by
  512. // right ptr is Having clause, if any
  513. SWQLNode_GroupBy() { m_dwNodeType = TYPE_SWQLNode_GroupBy; }
  514. void DebugDump();
  515. };
  516. //***************************************************************************
  517. //
  518. // SWQLNode_Having
  519. //
  520. // SWQLNode_Having
  521. // / \
  522. // SWQLNode_RelExpr NULL
  523. //
  524. //***************************************************************************
  525. #define TYPE_SWQLNode_Having (WQL_TOK_BASE + 14)
  526. struct SWQLNode_Having : SWQLNode
  527. {
  528. // left ptr is SQLNode_RelExpr pointing to HAVING expressions
  529. // right ptr is NULL
  530. SWQLNode_Having() { m_dwNodeType = TYPE_SWQLNode_Having; }
  531. void DebugDump();
  532. };
  533. //***************************************************************************
  534. //
  535. // SWQLNode_OrderBy
  536. //
  537. // SWQLNode_OrderBy
  538. // / \
  539. // SWQLNode_ColumnList NULL
  540. //
  541. //***************************************************************************
  542. #define TYPE_SWQLNode_OrderBy (WQL_TOK_BASE + 15)
  543. struct SWQLNode_OrderBy : SWQLNode
  544. {
  545. // left ptr is SWQLNode_ColumnList
  546. // right ptr is NULL
  547. SWQLNode_OrderBy() { m_dwNodeType = TYPE_SWQLNode_OrderBy; }
  548. void DebugDump();
  549. };
  550. //***************************************************************************
  551. //
  552. // SWQLNode_Datepart
  553. //
  554. // Contains a datepart call.
  555. //
  556. //***************************************************************************
  557. #define TYPE_SWQLNode_Datepart (WQL_TOK_BASE + 16)
  558. struct SWQLNode_Datepart : SWQLNode
  559. {
  560. int m_nDatepart; // One of WQL_TOK_YEAR, WQL_TOK_MONTH,
  561. // WQL_TOK_DAY, WQL_TOK_HOUR, WQL_TOK_MINUTE
  562. // WQL_TOK_SECOND
  563. SWQLColRef *m_pColRef; // The column to which DATEPART applies
  564. SWQLNode_Datepart() { m_dwNodeType = TYPE_SWQLNode_Datepart; m_nDatepart = 0; }
  565. ~SWQLNode_Datepart() { delete m_pColRef; }
  566. void DebugDump();
  567. };
  568. #endif