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.

813 lines
34 KiB

  1. /***************************************************************************/
  2. /* PARSE.H */
  3. /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
  4. /***************************************************************************/
  5. #define SQLNODEIDX int
  6. #define NO_SQLNODE (-1)
  7. #define ROOT_SQLNODE 0
  8. #define SQLNODE_ALLOC 16
  9. #define STRINGIDX int
  10. #define NO_STRING (-1)
  11. #define STRING_ALLOC 512 //was 128
  12. #define NO_SCALE (-1)
  13. #define OP_NONE 0
  14. #define OP_EQ 1
  15. #define OP_NE 2
  16. #define OP_LE 3
  17. #define OP_LT 4
  18. #define OP_GE 5
  19. #define OP_GT 6
  20. #define OP_IN 7
  21. #define OP_NOTIN 8
  22. #define OP_LIKE 9
  23. #define OP_NOTLIKE 10
  24. #define OP_NEG 11
  25. #define OP_PLUS 12
  26. #define OP_MINUS 13
  27. #define OP_TIMES 14
  28. #define OP_DIVIDEDBY 15
  29. #define OP_NOT 16
  30. #define OP_AND 17
  31. #define OP_OR 18
  32. #define OP_EXISTS 19
  33. #define AGG_AVG 1
  34. #define AGG_COUNT 2
  35. #define AGG_MAX 3
  36. #define AGG_MIN 4
  37. #define AGG_SUM 5
  38. #define SELECT_NOTSELECT 0
  39. #define SELECT_ALL 1
  40. #define SELECT_ANY 2
  41. #define SELECT_ONE 3
  42. #define SELECT_EXISTS 4
  43. #define NOT_IN_SORT_RECORD 0
  44. typedef struct tagSQLNODE { /* Node in SQL parse tree */
  45. UWORD sqlNodeType; /* NODE_TYPE_* */
  46. SWORD sqlDataType; /* TYPE_* (set by SemanticCheck()) */
  47. SWORD sqlSqlType; /* SQL_* (set by SemanticCheck()) */
  48. SDWORD sqlPrecision; /* Precision (set by SemanticCheck()) */
  49. SWORD sqlScale; /* Scale if sqlSqlType is */
  50. /* SQL_DECIMAL or SQL_NUMERIC */
  51. /* (set by SemanticCheck()) */
  52. BOOL sqlIsNull; /* Is expression value NULL (set */
  53. /* at execution time)? */
  54. union {
  55. double Double; /* When sqlDataType == TYPE_DOUBLE or */
  56. /* TYPE_INTEGER */
  57. LPUSTR String; /* When sqlDataType == TYPE_CHAR or */
  58. /* TYPE_NUMERIC */
  59. DATE_STRUCT Date; /* When sqlDataType == TYPE_DATE */
  60. TIME_STRUCT Time; /* When sqlDataType == TYPE_TIME */
  61. TIMESTAMP_STRUCT Timestamp; /* When sqlDataType == TYPE_TIMESTAMP */
  62. LPUSTR Binary; /* When sqlDataType == TYPE_BINARY */
  63. /* (length is in first four bytes) */
  64. } value;
  65. union {
  66. /* NODE_TYPE_ROOT */
  67. struct {
  68. LPISAM lpISAM; /* ISAM opening */
  69. HGLOBAL hParseArray; /* Handle to memory holding this */
  70. /* parse node array */
  71. int cParseArray; /* Number of elements in */
  72. /* hParseArray */
  73. int iParseArray; /* Last element in hParseArray */
  74. /* in use */
  75. HGLOBAL hStringArea; /* Handle to memory holding the */
  76. /* string area */
  77. LPUSTR lpStringArea; /* Pointer to memory holding the */
  78. /* string area */
  79. int cbStringArea; /* Size of string area */
  80. int ibStringArea; /* Last byte in string area in */
  81. /* use */
  82. SQLNODEIDX sql; /* CREATE, DROP, SELECT, INSERT, */
  83. /* DELETE, UPDATE, */
  84. /* CREATEINDEX, DROPINDEX, */
  85. /* PASSTHROUGH */
  86. SQLNODEIDX parameters; /* List of parameters for the */
  87. /* query (this points to a */
  88. /* PARAMETER or NO_SQLNODE) */
  89. BOOL passthroughParams; /* Are parameters from a */
  90. /* passthrough statement? */
  91. } root;
  92. /* NODE_TYPE_CREATE */
  93. struct {
  94. STRINGIDX Table; /* Offset into the string area */
  95. /* for the name of the table */
  96. SQLNODEIDX Columns; /* CREATECOLS */
  97. } create;
  98. /* NODE_TYPE_DROP */
  99. struct {
  100. STRINGIDX Table; /* Offset into the string area */
  101. /* for the name of the table */
  102. } drop;
  103. /* NODE_TYPE_CREATEINDEX */
  104. struct {
  105. STRINGIDX Index; /* Offset into the string area */
  106. /* for the name of the table */
  107. SQLNODEIDX Table; /* TABLE */
  108. SQLNODEIDX Columns; /* SORTCOLUMNS */
  109. BOOL Unique; /* Unique index? */
  110. } createindex;
  111. /* NODE_TYPE_DROPINDEX */
  112. struct {
  113. STRINGIDX Index; /* Offset into the string area */
  114. /* for the name of the index */
  115. } dropindex;
  116. /* NODE_TYPE_SELECT */
  117. struct {
  118. BOOL Distinct; /* TRUE, FALSE */
  119. SQLNODEIDX Values; /* VALUES */
  120. SQLNODEIDX Tables; /* TABLES */
  121. SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */
  122. /* NO_SQLNODE */
  123. SQLNODEIDX Groupbycolumns; /* GROUPBYCOLUMNS, NO_SQLNODE */
  124. SQLNODEIDX Having; /* BOOLEAN, COMPARISON, */
  125. /* NO_SQLNODE */
  126. SQLNODEIDX Sortcolumns; /* SORTCOLUMNS, NO_SQLNODE */
  127. /* The following elements are set by SemanticCheck(): */
  128. STRINGIDX SortDirective; /* Offset into the string area */
  129. /* to sort directive */
  130. UDWORD SortRecordsize; /* Size of records in sort file */
  131. UDWORD SortBookmarks; /* Offset of bookmarks in sort */
  132. /* record (one based) */
  133. SQLNODEIDX Aggregates; /* List of aggregates for the */
  134. /* query (this points to a */
  135. /* AGGREGATE or NO_SQLNODE) */
  136. UDWORD SortKeysize; /* Size of key in sort file */
  137. STRINGIDX DistinctDirective; /* Offset into the string area */
  138. /* to DISTINCT sort directive */
  139. UDWORD DistinctRecordsize; /* Size of records in DISTINCT */
  140. /* sort file */
  141. BOOL ImplicitGroupby; /* If TRUE, the user did not */
  142. /* specify a groupby but one */
  143. /* that contains the entire */
  144. /* table was added because */
  145. /* select list specified had */
  146. /* an aggregate function */
  147. SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
  148. /* UPDATE, NO_SQLNODE */
  149. /* The following elements are set by Optimize(): */
  150. BOOL fPushdownSort; /* Use ISAMSort() routines? */
  151. BOOL fMSAccess; /* Is this the funny MSAccess */
  152. /* query (see OPTIMIZE.C) ? */
  153. /* The following elements are set by ExecuteQuery(): */
  154. SDWORD RowCount; /* Number of rows */
  155. SDWORD CurrentRow; /* Current row fetched */
  156. STRINGIDX SortfileName; /* Name of the sortfile */
  157. HFILE Sortfile; /* Sortfile */
  158. BOOL ReturningDistinct; /* Does the sort file contain */
  159. /* results of a DISTINCT op */
  160. } select;
  161. /* NODE_TYPE_INSERT */
  162. struct {
  163. SQLNODEIDX Table; /* TABLE */
  164. SQLNODEIDX Columns; /* COLUMNS */
  165. SQLNODEIDX Values; /* VALUES, SELECT */
  166. } insert;
  167. /* NODE_TYPE_DELETE */
  168. struct {
  169. SQLNODEIDX Table; /* TABLE */
  170. SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */
  171. /* NO_SQLNODE */
  172. } delet;
  173. /* NODE_TYPE_UPDATE */
  174. struct {
  175. SQLNODEIDX Table; /* TABLE */
  176. SQLNODEIDX Updatevalues; /* UPDATEVALUES */
  177. SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */
  178. /* NO_SQLNODE */
  179. } update;
  180. /* NODE_TYPE_PASSTHROUGH */
  181. /* NODE_TYPE_TABLES */
  182. struct {
  183. SQLNODEIDX Table; /* TABLE */
  184. SQLNODEIDX Next; /* TABLES, NO_SQLNODE */
  185. } tables;
  186. /* NODE_TYPE_VALUES */
  187. struct {
  188. SQLNODEIDX Value; /* COLUMN, ALGEBRAIC, SCALAR, */
  189. /* AGGREGATE, NUMERIC, */
  190. /* STRING, PARAMETER, USER, */
  191. /* NULL */
  192. STRINGIDX Alias; /* Offset into the string area */
  193. /* for the alias (only used */
  194. /* for SELECT statements) */
  195. SQLNODEIDX Next; /* VALUES, NO_SQLNODE */
  196. } values;
  197. /* NODE_TYPE_COLUMNS */
  198. struct {
  199. SQLNODEIDX Column; /* COLUMN */
  200. SQLNODEIDX Next; /* COLUMNS, NO_SQLNODE */
  201. } columns;
  202. /* NODE_TYPE_SORTCOLUMNS */
  203. struct {
  204. SQLNODEIDX Column; /* COLUMN */
  205. BOOL Descending; /* TRUE, FALSE */
  206. SQLNODEIDX Next; /* SORTCOLUMNS, NO_SQLNODE */
  207. } sortcolumns;
  208. /* NODE_TYPE_GROUPBYCOLUMNS */
  209. struct {
  210. SQLNODEIDX Column; /* COLUMN */
  211. SQLNODEIDX Next; /* GROUPBYCOLUMNS, NO_SQLNODE */
  212. } groupbycolumns;
  213. /* NODE_TYPE_UPDATEVALUES */
  214. struct {
  215. SQLNODEIDX Column; /* COLUMN */
  216. SQLNODEIDX Value; /* COLUMN, ALGEBRAIC, SCALAR, */
  217. /* AGGREGATE, NUMERIC, */
  218. /* STRING, PARAMETER, USER, */
  219. /* NULL */
  220. SQLNODEIDX Next; /* UPDATEVALUES, NO_SQLNODE */
  221. } updatevalues;
  222. /* NODE_TYPE_CREATECOLS */
  223. struct {
  224. STRINGIDX Name; /* Offset into the string area */
  225. /* for the name of the column */
  226. STRINGIDX Type; /* Offset into the string area */
  227. /* for the data type name */
  228. UWORD Params; /* Number of create params */
  229. UDWORD Param1; /* Value of param 1 (if any) */
  230. UDWORD Param2; /* Value of param 2 (if any) */
  231. SQLNODEIDX Next; /* CREATECOLS, NO_SQLNODE */
  232. /* The following elements are set by SemanticCheck(): */
  233. UWORD iSqlType; /* Index into SQLTypes[] of */
  234. /* the type of the column */
  235. } createcols;
  236. /* NODE_TYPE_BOOLEAN */
  237. struct {
  238. UWORD Operator; /* OP_NOT, OP_AND, or OP_OR */
  239. SQLNODEIDX Left; /* BOOLEAN, COMPARISON, */
  240. SQLNODEIDX Right; /* BOOLEAN, COMPARISON, */
  241. /* NO_SQLNODE */
  242. } boolean;
  243. /* NODE_TYPE_COMPARISON */
  244. struct {
  245. UWORD Operator; /* OP_EQ, OP_NE, OP_LE, OP_LT, */
  246. /* OP_GE, OP_GT, OP_LIKE, */
  247. /* OP_NOTLIKE, OP_IN, */
  248. /* OP_NOTIN, OP_EXISTS */
  249. UWORD SelectModifier; /* SELECT_NOTSELECT, */
  250. /* SELECT_ALL, SELECT_ANY, */
  251. /* SELECT_ONE, SELECT_EXISTS */
  252. SQLNODEIDX Left; /* COLUMN, ALGEBRAIC, SCALAR, */
  253. /* AGGREGATE, NUMERIC, */
  254. /* STRING, PARAMETER, USER, */
  255. /* SELECT, NULL */
  256. SQLNODEIDX Right; /* COLUMN, ALGEBRAIC, SCALAR, */
  257. /* AGGREGATE, NUMERIC, */
  258. /* STRING, PARAMETER, USER, */
  259. /* VALUES (for IN/NOTIN op), */
  260. /* SELECT, NULL */
  261. /* The following elements are set by Optimize(): */
  262. UWORD fSelectivity; /* Selectivity the restriction */
  263. SQLNODEIDX NextRestrict; /* COMPARISON, NO_SQLNODE */
  264. /* The next restriction on the */
  265. /* list of restrictions */
  266. } comparison;
  267. /* NODE_TYPE_ALGEBRAIC */
  268. struct {
  269. UWORD Operator; /* OP_NEG, OP_PLUS, */
  270. /* OP_MINUS, OP_TIMES, */
  271. /* OP_DIVIDEDBY */
  272. SQLNODEIDX Left; /* COLUMN, ALGEBRAIC, SCALAR, */
  273. /* AGGREGATE, NUMERIC, */
  274. /* STRING, PARAMETER, USER, */
  275. /* NULL */
  276. SQLNODEIDX Right; /* COLUMN, ALGEBRAIC, SCALAR, */
  277. /* AGGREGATE, NUMERIC, */
  278. /* STRING, PARAMETER, USER, */
  279. /* NULL, NO_SQLNODE */
  280. /* The following elements are set by SemanticCheck(): */
  281. STRINGIDX Value; /* Value used to evaluate */
  282. /* expressions */
  283. STRINGIDX WorkBuffer1; /* Workbuffer used to evaluate */
  284. /* NUMERIC multiply & divide */
  285. STRINGIDX WorkBuffer2; /* Workbuffer used to evaluate */
  286. /* NUMERIC divide */
  287. STRINGIDX WorkBuffer3; /* Workbuffer used to evaluate */
  288. /* NUMERIC divide */
  289. UDWORD DistinctOffset; /* The offset the column is in */
  290. /* in the sort DISTINCT */
  291. /* record (one based). */
  292. UDWORD DistinctLength; /* The length of the column in */
  293. /* the sort DISTINCT record. */
  294. SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
  295. /* UPDATE */
  296. } algebraic;
  297. /* NODE_TYPE_SCALAR */
  298. struct {
  299. STRINGIDX Function; /* Name of the function */
  300. SQLNODEIDX Arguments; /* VALUES, NO_SQLNODE */
  301. /* The following elements are set by SemanticCheck(): */
  302. UWORD Id; /* Scaler function id */
  303. UWORD Interval; /* Interval for TIMESTAMPADD */
  304. /* and TIMESTAMPDIFF */
  305. STRINGIDX Value; /* Value used to evaluate */
  306. /* expressions */
  307. UDWORD DistinctOffset; /* The offset the column is in */
  308. /* in the sort DISTINCT */
  309. /* record (one based). */
  310. UDWORD DistinctLength; /* The length of the column in */
  311. /* the sort DISTINCT record. */
  312. SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
  313. /* UPDATE */
  314. } scalar;
  315. /* NODE_TYPE_AGGREGATE */
  316. struct {
  317. UWORD Operator; /* AGG_AVE, AGG_COUNT, */
  318. /* AGG_MAX, AGG_MIN, AGG_SUM */
  319. SQLNODEIDX Expression; /* COLUMN, ALGEBRAIC, SCALAR, */
  320. /* AGGREGATE, NUMERIC, */
  321. /* STRING, PARAMETER, USER, */
  322. /* NULL */
  323. /* The following elements are set by SemanticCheck(): */
  324. STRINGIDX Value; /* Column value used to */
  325. /* evaluate expressions */
  326. UDWORD Offset; /* The offset the column is in */
  327. /* in the sort record (one */
  328. /* based). */
  329. UDWORD Length; /* The length of the column in */
  330. /* the sort record. */
  331. UDWORD DistinctOffset; /* The offset the column is in */
  332. /* in the sort DISTINCT */
  333. /* record (one based). */
  334. UDWORD DistinctLength; /* The length of the column in */
  335. /* the sort DISTINCT record. */
  336. SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
  337. /* UPDATE */
  338. SQLNODEIDX Next; /* Rest of list of AGG */
  339. /* functions for the query */
  340. /* (this points to an */
  341. /* AGGREGATE or NO_SQLNODE) */
  342. /* The following elements are set at execution time: */
  343. double Count; /* Number of records that had */
  344. /* a non-NULL value */
  345. } aggregate;
  346. /* NODE_TYPE_TABLE */
  347. struct {
  348. STRINGIDX Name; /* Offset into the string area */
  349. /* for the name of the table */
  350. STRINGIDX Qualifier; /* Offset into the string area */
  351. /* for the qulaifier of the table */
  352. STRINGIDX Alias; /* Offset into the string area */
  353. /* for the name of the alias */
  354. SQLNODEIDX OuterJoinFromTables;/* TABLES, NO_SQLNODE */
  355. SQLNODEIDX OuterJoinPredicate; /* BOOLEAN, COMPARISON, */
  356. /* NO_SQLNODE */
  357. /* The following elements are set by SemanticCheck(): */
  358. LPISAMTABLEDEF Handle; /* Table handle */
  359. /* The following elements are set by Optimize(): */
  360. UWORD cRestrict; /* The number of Restrict nodes */
  361. SQLNODEIDX Restrict; /* COMPARISON, NO_SQLNODE (if */
  362. /* this points to a comparison */
  363. /* node, the node is somewhere */
  364. /* in the predicate, and is in */
  365. /* the form: */
  366. /* */
  367. /* <column> <op> <constant> */
  368. /* */
  369. /* where <column> is some */
  370. /* column of this table) */
  371. UWORD Sortsequence; /* The relative position of */
  372. /* this table when sorting */
  373. UWORD Sortcount; /* The number of sort columns */
  374. /* for this table */
  375. SQLNODEIDX Sortcolumns; /* SORTCOLUMNS, NO_SQLNODE (the */
  376. /* first in the list of sort */
  377. /* columns for this table) */
  378. /* The following elements are set at execution time: */
  379. BOOL AllNull; /* Use NULL as value for all */
  380. /* columns in current row */
  381. BOOL Rewound; /* Is table positioned before */
  382. /* first record? */
  383. } table;
  384. /* NODE_TYPE_COLUMN */
  385. struct {
  386. STRINGIDX Tablealias; /* Offset into the string area */
  387. /* for the name of the alias */
  388. STRINGIDX Column; /* Offset into the string area */
  389. /* for the name of the column */
  390. STRINGIDX Qualifier; /* Offset into the string area */
  391. /* for the name of the */
  392. /* qualifier */
  393. BOOL MatchedAlias; /* indicates if the TableAlias */
  394. /* refers to a table name or an*/
  395. /* alias. */
  396. SQLNODEIDX TableIndex; /* index of table node to which*/
  397. /* column belongs */
  398. /* This renders the info above */
  399. /* redundant. */
  400. /* The following elements are set by SemanticCheck(): */
  401. SQLNODEIDX Table; /* TABLE, NO_SQLNODE. Table */
  402. /* of the column. If */
  403. /* NO_SQLNODE, the column is */
  404. /* in sort record. */
  405. SWORD Id; /* Ordinal position of column */
  406. STRINGIDX Value; /* Column value used to */
  407. /* evaluate expressions */
  408. BOOL InSortRecord; /* Is this column in the sort */
  409. /* record? */
  410. UDWORD Offset; /* The offset the column is in */
  411. /* in the sort record (one */
  412. /* based). */
  413. UDWORD Length; /* The length of the column if */
  414. /* it is in the sort record. */
  415. UDWORD DistinctOffset; /* The offset the column is in */
  416. /* in the sort DISTINCT */
  417. /* record (one based). */
  418. UDWORD DistinctLength; /* The length of the column in */
  419. /* the sort DISTINCT record. */
  420. SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
  421. /* UPDATE */
  422. } column;
  423. /* NODE_TYPE_STRING */
  424. struct {
  425. STRINGIDX Value; /* Offset into the string area */
  426. /* for the string */
  427. } string;
  428. /* NODE_TYPE_NUMERIC */
  429. struct {
  430. double Value;
  431. STRINGIDX Numeric;
  432. } numeric;
  433. /* NODE_TYPE_PARAMETER */
  434. struct {
  435. UWORD Id; /* Ordinal position of parameter */
  436. SQLNODEIDX Next; /* Rest of list of parameters for */
  437. /* the query (this points to a */
  438. /* PARAMETER or NO_SQLNODE) */
  439. /* The following elements are set by SemanticCheck(): */
  440. STRINGIDX Value; /* Parameter value used to */
  441. /* evaluate expressions */
  442. /* The following elements are set at execution time: */
  443. BOOL AtExec; /* Value to be provided by */
  444. /* ParamData()/PutData() */
  445. } parameter;
  446. /* NODE_TYPE_USER */
  447. /* NODE_TYPE_NULL */
  448. /* NODE_TYPE_DATE */
  449. struct {
  450. DATE_STRUCT Value;
  451. } date;
  452. /* NODE_TYPE_TIME */
  453. struct {
  454. TIME_STRUCT Value;
  455. } time;
  456. /* NODE_TYPE_TIMESTAMP */
  457. struct {
  458. TIMESTAMP_STRUCT Value;
  459. } timestamp;
  460. } node;
  461. } SQLNODE,
  462. FAR * LPSQLNODE;
  463. #define LPSQLTREE LPSQLNODE
  464. #define NODE_TYPE_NONE 0
  465. #define NODE_TYPE_ROOT 1
  466. #define NODE_TYPE_CREATE 2
  467. #define NODE_TYPE_DROP 3
  468. #define NODE_TYPE_SELECT 4
  469. #define NODE_TYPE_INSERT 5
  470. #define NODE_TYPE_DELETE 6
  471. #define NODE_TYPE_UPDATE 7
  472. #define NODE_TYPE_PASSTHROUGH 8
  473. #define NODE_TYPE_TABLES 9
  474. #define NODE_TYPE_VALUES 10
  475. #define NODE_TYPE_COLUMNS 11
  476. #define NODE_TYPE_SORTCOLUMNS 12
  477. #define NODE_TYPE_GROUPBYCOLUMNS 13
  478. #define NODE_TYPE_UPDATEVALUES 14
  479. #define NODE_TYPE_CREATECOLS 15
  480. #define NODE_TYPE_BOOLEAN 16
  481. #define NODE_TYPE_COMPARISON 17
  482. #define NODE_TYPE_ALGEBRAIC 18
  483. #define NODE_TYPE_AGGREGATE 19
  484. #define NODE_TYPE_TABLE 20
  485. #define NODE_TYPE_COLUMN 21
  486. #define NODE_TYPE_STRING 22
  487. #define NODE_TYPE_NUMERIC 23
  488. #define NODE_TYPE_PARAMETER 24
  489. #define NODE_TYPE_USER 25
  490. #define NODE_TYPE_NULL 26
  491. #define NODE_TYPE_DATE 27
  492. #define NODE_TYPE_TIME 28
  493. #define NODE_TYPE_TIMESTAMP 29
  494. #define NODE_TYPE_CREATEINDEX 30
  495. #define NODE_TYPE_DROPINDEX 31
  496. #define NODE_TYPE_SCALAR 32
  497. //Class used to re-convert WHERE predicate back into character string
  498. class PredicateParser
  499. {
  500. private:
  501. LPSQLTREE FAR *lplpSql;
  502. LPISAMTABLEDEF lpISAMTableDef;
  503. BOOL fError;
  504. BOOL fSupportLIKEs;
  505. //Generates string for a comparision expression
  506. void GenerateComparisonString(char* lpLeftString, char* lpRightString, UWORD wOperator, UWORD wSelectModifier, char** lpOutputStr);
  507. //Generates string for a boolean expression
  508. void GenerateBooleanString(char* lpLeftString, char* lpRightString, UWORD wOperator, char** lpOutputStr);
  509. //Generates string for an aggregate expression
  510. void GenerateAggregateString(char* lpLeftString, UWORD wOperator, char** lpOutputStr);
  511. //Generates string for an algebraic expression
  512. void GenerateAlgebraicString(char* lpLeftString, char* lpRightString, UWORD wOperator, char** lpOutputStr);
  513. //Builds a column reference
  514. void GenerateColumnRef(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
  515. public:
  516. //Generates WHERE predicate string from SQLNODETREE
  517. void GeneratePredicateString(LPSQLNODE lpSqlNode, char** lpOutputStr, BOOL fIsSQL89 = TRUE);
  518. //Builds GROUP BY statement
  519. void GenerateGroupByString(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
  520. //Builds ORDER BY statement
  521. void GenerateOrderByString(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
  522. // PredicateParser(LPSQLTREE FAR *lplpTheSql, SQLNODEIDX iPredicate)
  523. // {lplpSql = lplpTheSql; Predicate = iPredicate;}
  524. PredicateParser(LPSQLTREE FAR *lplpTheSql, LPISAMTABLEDEF lpISAMTblDef, BOOL fLIKEs = TRUE)
  525. {lplpSql = lplpTheSql; lpISAMTableDef = lpISAMTblDef; fError = FALSE; fSupportLIKEs = fLIKEs;}
  526. ~PredicateParser() {;}
  527. };
  528. class PassthroughLookupTable
  529. {
  530. private:
  531. char tableAlias [MAX_QUALIFIER_NAME_LENGTH + 1];
  532. char columnName [MAX_COLUMN_NAME_LENGTH + 1];
  533. public:
  534. BOOL SetTableAlias(char* tblAlias);
  535. char* GetTableAlias() {return tableAlias;}
  536. BOOL SetColumnName(char* columName);
  537. char* GetColumnName() {return columnName;}
  538. PassthroughLookupTable();
  539. };
  540. void TidyupPassthroughMap(CMapWordToPtr* passthroughMap);
  541. class VirtualInstanceInfo
  542. {
  543. public:
  544. //each element in the CMapStringToPtr is keyed on
  545. //TableAlias.ColumnName
  546. long cElements; //number of elements in this array
  547. long cCycle; //value change cycle for instances
  548. VirtualInstanceInfo();
  549. ~VirtualInstanceInfo();
  550. };
  551. class VirtualInstanceManager
  552. {
  553. private:
  554. CMapStringToPtr* virtualInfo;
  555. char* ConstructKey(LPCTSTR TableAlias, LPCTSTR ColumnName);
  556. IWbemClassObject* GetWbemObject(CBString& myTableAlias, IWbemClassObject* myInstance);
  557. public:
  558. long currentInstance; //zero-based index
  559. long cNumberOfInstances;
  560. void AddColumnInstance(LPCTSTR TableAlias, LPCTSTR ColumnName, VirtualInstanceInfo* col);
  561. long GetArrayIndex(LPCTSTR TableAlias, LPCTSTR ColumnName, long instanceNum);
  562. // void Testy();
  563. void Load(CMapWordToPtr* passthroughMap, IWbemClassObject* myInstance);
  564. BOOL GetVariantValue(CBString& myTableAlias, CBString& myColumnName, IWbemClassObject* myInstance, VARIANT FAR* myVal);
  565. VirtualInstanceManager();
  566. ~VirtualInstanceManager();
  567. };
  568. class TableColumnList
  569. {
  570. public:
  571. SQLNODEIDX idxColumnName; //column info
  572. SQLNODEIDX idxTableAlias; //table alias for column
  573. LPISAMTABLEDEF lpISAMTableDef; //table info
  574. TableColumnList* Next; //Next item in list
  575. TableColumnList(SQLNODEIDX idx, SQLNODEIDX idxAlias, LPISAMTABLEDEF lpTableDef)
  576. {idxColumnName = idx; idxTableAlias = idxAlias; lpISAMTableDef = lpTableDef; Next = NULL;}
  577. ~TableColumnList() {delete Next;}
  578. };
  579. #define WQL_SINGLE_TABLE 1
  580. #define WQL_MULTI_TABLE 2
  581. class TableColumnInfo
  582. {
  583. private:
  584. LPSQLTREE FAR *lplpSql;
  585. LPSQLTREE FAR * lplpSqlNode;
  586. BOOL fIsValid;
  587. ULONG theMode;
  588. STRINGIDX idxTableQualifer;
  589. BOOL fDistinct;
  590. BOOL fHasScalarFunction;
  591. BOOL fIsSelectStar;
  592. BOOL m_aggregateExists;
  593. void Analize(LPSQLNODE lpNode);
  594. void StringConcat(char** resultString, char* myStr);
  595. // void AddJoin(_bstr_t & tableList, SQLNODEIDX joinidx);
  596. void AddJoinPredicate(char** tableList, SQLNODEIDX predicateidx);
  597. public:
  598. TableColumnList* lpList;
  599. void BuildTableList(char** tableList, BOOL &fIsSQL89, SQLNODEIDX idx = NO_SQLNODE);
  600. //Check if there is zero or one column/table entires in list
  601. //This is used to check for COUNT(*)
  602. BOOL IsZeroOrOneList();
  603. //Have any aggregate functions been detected
  604. BOOL HasAggregateFunctions() {return m_aggregateExists;}
  605. //Is SELECT DISTINCT select-list FROM .....
  606. BOOL IsDistinct() {return fDistinct;}
  607. //Is SELECT * FROM ...
  608. BOOL IsSelectStar() {return fIsSelectStar;}
  609. //Was table column info parsed successfully
  610. BOOL IsValid() {return fIsValid;}
  611. //Indicate if query contains scalar function
  612. BOOL HasScalarFunction() {return fHasScalarFunction;}
  613. //Builds a select list for the chosen table
  614. void BuildSelectList(LPISAMTABLEDEF lpTableDef, char** lpSelectListStr, BOOL fIsSQL89 = TRUE, CMapWordToPtr** ppPassthroughMap = NULL);
  615. //Builds whole WQL statement
  616. void BuildFullWQL(char** lpWQLStr, CMapWordToPtr** ppPassthroughMap = NULL);
  617. STRINGIDX GetTableQualifier() {return idxTableQualifer;}
  618. //Indicates if at least one column in the specified table
  619. //is refernced in the SQL statement
  620. BOOL IsTableReferenced(LPISAMTABLEDEF lpTableDef);
  621. TableColumnInfo(LPSQLTREE FAR *lplpTheSql, LPSQLTREE FAR * lpSqlN, ULONG mode = WQL_SINGLE_TABLE);
  622. ~TableColumnInfo() {delete lpList;}
  623. };
  624. #define DATETIME_FORMAT_LEN 21
  625. #define DATETIME_DATE_LEN 8
  626. #define DATETIME_TIME_LEN 6
  627. #define DATETIME_YEAR_LEN 4
  628. #define DATETIME_MONTH_LEN 2
  629. #define DATETIME_DAY_LEN 2
  630. #define DATETIME_HOUR_LEN 2
  631. #define DATETIME_MIN_LEN 2
  632. #define DATETIME_SEC_LEN 2
  633. #define DATETIME_MICROSEC_LEN 6
  634. class DateTimeParser
  635. {
  636. private:
  637. BOOL fIsValid;
  638. BOOL fValidDate;
  639. BOOL fValidTime;
  640. BOOL fIsaTimestamp;
  641. BOOL fIsaDate;
  642. BOOL fIsaTime;
  643. ULONG m_year;
  644. ULONG m_month;
  645. ULONG m_day;
  646. ULONG m_hour;
  647. ULONG m_min;
  648. ULONG m_sec;
  649. ULONG m_microSec;
  650. char dateTimeBuff[DATETIME_FORMAT_LEN + 1];
  651. char tempBuff[DATETIME_MICROSEC_LEN + 1];
  652. BOOL IsNumber(char bChar);
  653. void FetchField(char* lpStr, WORD wFieldLen, ULONG &wValue);
  654. void ValidateFields();
  655. public:
  656. BOOL IsValid() {return fIsValid;}
  657. BOOL IsTimestamp() {return fIsaTimestamp;}
  658. BOOL IsDate() {return fIsaDate;}
  659. BOOL IsTime() {return fIsaTime;}
  660. ULONG GetYear() {return m_year;}
  661. ULONG GetMonth() {return m_month;}
  662. ULONG GetDay() {return m_day;}
  663. ULONG GetHour() {return m_hour;}
  664. ULONG GetMin() {return m_min;}
  665. ULONG GetSec() {return m_sec;}
  666. ULONG GetMicroSec() {return m_microSec;}
  667. DateTimeParser(BSTR dateTimeStr);
  668. ~DateTimeParser() {;}
  669. };
  670. /***************************************************************************/
  671. #define ToNode(lpSql, idx) (&((lpSql)[idx]))
  672. #define ToString(lpSql, idx) (&((lpSql)->node.root.lpStringArea[idx]))
  673. /***************************************************************************/
  674. RETCODE INTFUNC Parse(LPSTMT, LPISAM, LPUSTR, SDWORD, LPSQLTREE FAR *);
  675. SQLNODEIDX INTFUNC AllocateNode(LPSQLTREE FAR *, UWORD);
  676. STRINGIDX INTFUNC AllocateSpace(LPSQLTREE FAR *, SWORD);
  677. STRINGIDX INTFUNC AllocateString(LPSQLTREE FAR *, LPUSTR);
  678. void INTFUNC FreeTree(LPSQLTREE);
  679. /***************************************************************************/