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.

200 lines
6.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Copyright (C) Microsoft Corporation, 1991-2000.
  4. //
  5. // File: Parstree.hxx
  6. //
  7. // Contents: Converts OLE-DB command tree into CColumns, CSort, CRestriction
  8. //
  9. // Classes: CParseCommandTree
  10. //
  11. // History: 31 May 95 AlanW Created
  12. //
  13. //--------------------------------------------------------------------------
  14. #pragma once
  15. #define SCOPE_COUNT_GROWSIZE 5
  16. // What is good value? One that prevents stack overflow.
  17. const ULONG RECURSION_LIMIT = 1000;
  18. class CParseCommandTree
  19. {
  20. public:
  21. CParseCommandTree( void ) :
  22. _cols( 0 ),
  23. _sort( 0 ),
  24. _prst( 0 ),
  25. _categ( 0 ),
  26. _pidmap( ),
  27. _scError( S_OK ),
  28. _pErrorNode( 0 ),
  29. _cMaxResults( 0 ),
  30. _cFirstRows( 0 ),
  31. _cScopes( 0 ),
  32. _xaMachines( SCOPE_COUNT_GROWSIZE ),
  33. _xaScopes( SCOPE_COUNT_GROWSIZE ),
  34. _xaCatalogs( SCOPE_COUNT_GROWSIZE ),
  35. _xaFlags( SCOPE_COUNT_GROWSIZE ),
  36. _cRecursionLimit( RECURSION_LIMIT )
  37. {
  38. }
  39. ~CParseCommandTree( void );
  40. void ParseTree( CDbCmdTreeNode * pTree );
  41. CRestriction* ParseExpression( CDbCmdTreeNode * pTree );
  42. CPidMapperWithNames & GetPidmap() { return _pidmap; }
  43. CColumnSet & GetOutputColumns() { return _cols; }
  44. CSortSet & GetSortColumns() { return _sort; }
  45. CRestriction * GetRestriction() { return _prst; }
  46. CCategorizationSet & GetCategorization() { return _categ; }
  47. CRestriction * AcquireRestriction()
  48. {
  49. CRestriction * pRst = _prst;
  50. _prst = 0;
  51. return pRst;
  52. }
  53. ULONG GetMaxResults() { return _cMaxResults; }
  54. void SetMaxResults( ULONG cMaxResults ) { _cMaxResults = cMaxResults; }
  55. ULONG GetFirstRows() { return _cFirstRows; }
  56. void SetFirstRows( ULONG cFirstRows ) { _cFirstRows = cFirstRows; }
  57. void GetScopes( unsigned & cScopes,
  58. XGrowable<const WCHAR *,SCOPE_COUNT_GROWSIZE> & xaScopes,
  59. XGrowable<ULONG,SCOPE_COUNT_GROWSIZE> & xaFlags,
  60. XGrowable<const WCHAR *,SCOPE_COUNT_GROWSIZE> & xaCatalogs,
  61. XGrowable<const WCHAR *,SCOPE_COUNT_GROWSIZE> & xaMachines )
  62. {
  63. if ( 0 < _cScopes )
  64. {
  65. xaScopes.Copy( _xaScopes.Get(), _cScopes, 0 );
  66. xaMachines.Copy( _xaMachines.Get(), _cScopes, 0 );
  67. xaCatalogs.Copy( _xaCatalogs.Get(), _cScopes, 0 );
  68. xaFlags.Copy( _xaFlags.Get(), _cScopes, 0 );
  69. cScopes = _cScopes;
  70. }
  71. }
  72. protected:
  73. void ParseProjection( CDbCmdTreeNode * pTree );
  74. void ParseProjectList( CDbCmdTreeNode * pTree, CColumnSet & Cols );
  75. void ParseSort( CDbCmdTreeNode * pTree );
  76. void ParseSortList( CDbCmdTreeNode * pTree );
  77. void ParseRestriction( CDbCmdTreeNode * pTree );
  78. void ParseCategorization( CDbCmdTreeNode * pTree );
  79. CRestriction* ParseContentExpression( CDbCmdTreeNode * pTree );
  80. void ParseTopNode( CDbCmdTreeNode *pTree );
  81. void ParseFirstRowsNode( CDbCmdTreeNode *pTree );
  82. void ParseScope( CDbCmdTreeNode * pTree );
  83. void ParseScopeListElements( CDbCmdTreeNode * pTree );
  84. void ParseMultiScopes( CDbCmdTreeNode * pTree );
  85. private:
  86. void VerifyOperatorType( CDbCmdTreeNode * pNode, DBCOMMANDOP OpType );
  87. void VerifyValueType( CDbCmdTreeNode * pNode, DBVALUEKIND ValueType );
  88. unsigned CheckOperatorArity( CDbCmdTreeNode * pNode, int cOperands );
  89. void SetError( CDbCmdTreeNode * pNode, SCODE scErr = E_INVALIDARG );
  90. PROPID GetColumnPropSpec( CDbCmdTreeNode * pNode, CFullPropSpec & Prop );
  91. BOOL GetValue( CDbCmdTreeNode * pNode , CStorageVariant & val );
  92. void CheckRecursionLimit()
  93. {
  94. if ( 0 == _cRecursionLimit )
  95. THROW( CException(QUERY_E_TOOCOMPLEX) );
  96. _cRecursionLimit--;
  97. }
  98. //
  99. // The results of the parse
  100. //
  101. CRestriction* _prst; // restriction expression (select clause)
  102. // CATEGORIZATIONSET _categ; // categorization set (nesting nodes)
  103. CStorageVariant _tmpValue; // used for temporary value retrieval
  104. ULONG _cMaxResults; // limit on # query results
  105. ULONG _cFirstRows;
  106. CColumnSet _cols; // columns in the project list
  107. CSortSet _sort; // sort specification
  108. CCategorizationSet _categ; // categorization specifications
  109. CPidMapperWithNames _pidmap; // properties and names used
  110. ULONG _cRecursionLimit; // Limits how many nodes we can visit
  111. // stack protection.
  112. //
  113. // Scope information
  114. //
  115. ULONG _cScopes;
  116. XGrowable<WCHAR const *,SCOPE_COUNT_GROWSIZE> _xaMachines;
  117. XGrowable<WCHAR const *,SCOPE_COUNT_GROWSIZE> _xaScopes;
  118. XGrowable<WCHAR const *,SCOPE_COUNT_GROWSIZE> _xaCatalogs;
  119. XGrowable<ULONG,SCOPE_COUNT_GROWSIZE> _xaFlags;
  120. //
  121. // Error information
  122. //
  123. SCODE _scError; // first error code
  124. CDbCmdTreeNode* _pErrorNode; // first node with error
  125. };
  126. //+---------------------------------------------------------------------------
  127. //
  128. // Method: CParseCommandTree::VerifyValueType, private
  129. //
  130. // Synopsis: Verify that a tree node has the proper argument type
  131. //
  132. // Arguments: [pNode] -- CDbCmdTreeNode node to check
  133. // [eKind] -- expected value kind
  134. //
  135. // Returns: nothing.
  136. //
  137. // History: 31 May 95 AlanW Created
  138. //
  139. //----------------------------------------------------------------------------
  140. inline
  141. void CParseCommandTree::VerifyValueType(
  142. CDbCmdTreeNode* pNode,
  143. DBVALUEKIND eKind)
  144. {
  145. if (pNode->GetValueType() != eKind)
  146. SetError(pNode, E_INVALIDARG);
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Method: CParseCommandTree::VerifyOperatorType, private
  151. //
  152. // Synopsis: Verify that a tree node has the proper operator
  153. //
  154. // Arguments: [pNode] -- CDbCmdTreeNode node to check
  155. // [op] -- expected operator value
  156. //
  157. // Returns: nothing.
  158. //
  159. // History: 31 May 95 AlanW Created
  160. //
  161. //----------------------------------------------------------------------------
  162. inline
  163. void CParseCommandTree::VerifyOperatorType(
  164. CDbCmdTreeNode* pNode,
  165. DBCOMMANDOP op )
  166. {
  167. if (pNode->GetCommandType() != op)
  168. SetError(pNode, E_INVALIDARG);
  169. }