|
|
/***************************************************************************/ /* PARSE.H */ /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */ /***************************************************************************/
#define SQLNODEIDX int
#define NO_SQLNODE (-1)
#define ROOT_SQLNODE 0
#define SQLNODE_ALLOC 16
#define STRINGIDX int
#define NO_STRING (-1)
#define STRING_ALLOC 512 //was 128
#define NO_SCALE (-1)
#define OP_NONE 0
#define OP_EQ 1
#define OP_NE 2
#define OP_LE 3
#define OP_LT 4
#define OP_GE 5
#define OP_GT 6
#define OP_IN 7
#define OP_NOTIN 8
#define OP_LIKE 9
#define OP_NOTLIKE 10
#define OP_NEG 11
#define OP_PLUS 12
#define OP_MINUS 13
#define OP_TIMES 14
#define OP_DIVIDEDBY 15
#define OP_NOT 16
#define OP_AND 17
#define OP_OR 18
#define OP_EXISTS 19
#define AGG_AVG 1
#define AGG_COUNT 2
#define AGG_MAX 3
#define AGG_MIN 4
#define AGG_SUM 5
#define SELECT_NOTSELECT 0
#define SELECT_ALL 1
#define SELECT_ANY 2
#define SELECT_ONE 3
#define SELECT_EXISTS 4
#define NOT_IN_SORT_RECORD 0
typedef struct tagSQLNODE { /* Node in SQL parse tree */ UWORD sqlNodeType; /* NODE_TYPE_* */ SWORD sqlDataType; /* TYPE_* (set by SemanticCheck()) */ SWORD sqlSqlType; /* SQL_* (set by SemanticCheck()) */ SDWORD sqlPrecision; /* Precision (set by SemanticCheck()) */ SWORD sqlScale; /* Scale if sqlSqlType is */ /* SQL_DECIMAL or SQL_NUMERIC */ /* (set by SemanticCheck()) */ BOOL sqlIsNull; /* Is expression value NULL (set */ /* at execution time)? */ union { double Double; /* When sqlDataType == TYPE_DOUBLE or */ /* TYPE_INTEGER */ LPUSTR String; /* When sqlDataType == TYPE_CHAR or */ /* TYPE_NUMERIC */ DATE_STRUCT Date; /* When sqlDataType == TYPE_DATE */ TIME_STRUCT Time; /* When sqlDataType == TYPE_TIME */ TIMESTAMP_STRUCT Timestamp; /* When sqlDataType == TYPE_TIMESTAMP */ LPUSTR Binary; /* When sqlDataType == TYPE_BINARY */ /* (length is in first four bytes) */ } value; union {
/* NODE_TYPE_ROOT */ struct { LPISAM lpISAM; /* ISAM opening */ HGLOBAL hParseArray; /* Handle to memory holding this */ /* parse node array */ int cParseArray; /* Number of elements in */ /* hParseArray */ int iParseArray; /* Last element in hParseArray */ /* in use */ HGLOBAL hStringArea; /* Handle to memory holding the */ /* string area */ LPUSTR lpStringArea; /* Pointer to memory holding the */ /* string area */ int cbStringArea; /* Size of string area */ int ibStringArea; /* Last byte in string area in */ /* use */ SQLNODEIDX sql; /* CREATE, DROP, SELECT, INSERT, */ /* DELETE, UPDATE, */ /* CREATEINDEX, DROPINDEX, */ /* PASSTHROUGH */ SQLNODEIDX parameters; /* List of parameters for the */ /* query (this points to a */ /* PARAMETER or NO_SQLNODE) */ BOOL passthroughParams; /* Are parameters from a */ /* passthrough statement? */ } root;
/* NODE_TYPE_CREATE */ struct { STRINGIDX Table; /* Offset into the string area */ /* for the name of the table */ SQLNODEIDX Columns; /* CREATECOLS */ } create;
/* NODE_TYPE_DROP */ struct { STRINGIDX Table; /* Offset into the string area */ /* for the name of the table */ } drop;
/* NODE_TYPE_CREATEINDEX */ struct { STRINGIDX Index; /* Offset into the string area */ /* for the name of the table */ SQLNODEIDX Table; /* TABLE */ SQLNODEIDX Columns; /* SORTCOLUMNS */ BOOL Unique; /* Unique index? */ } createindex;
/* NODE_TYPE_DROPINDEX */ struct { STRINGIDX Index; /* Offset into the string area */ /* for the name of the index */ } dropindex;
/* NODE_TYPE_SELECT */ struct { BOOL Distinct; /* TRUE, FALSE */ SQLNODEIDX Values; /* VALUES */ SQLNODEIDX Tables; /* TABLES */ SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */ /* NO_SQLNODE */ SQLNODEIDX Groupbycolumns; /* GROUPBYCOLUMNS, NO_SQLNODE */ SQLNODEIDX Having; /* BOOLEAN, COMPARISON, */ /* NO_SQLNODE */ SQLNODEIDX Sortcolumns; /* SORTCOLUMNS, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */ STRINGIDX SortDirective; /* Offset into the string area */ /* to sort directive */ UDWORD SortRecordsize; /* Size of records in sort file */ UDWORD SortBookmarks; /* Offset of bookmarks in sort */ /* record (one based) */ SQLNODEIDX Aggregates; /* List of aggregates for the */ /* query (this points to a */ /* AGGREGATE or NO_SQLNODE) */ UDWORD SortKeysize; /* Size of key in sort file */ STRINGIDX DistinctDirective; /* Offset into the string area */ /* to DISTINCT sort directive */ UDWORD DistinctRecordsize; /* Size of records in DISTINCT */ /* sort file */ BOOL ImplicitGroupby; /* If TRUE, the user did not */ /* specify a groupby but one */ /* that contains the entire */ /* table was added because */ /* select list specified had */ /* an aggregate function */ SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */ /* UPDATE, NO_SQLNODE */
/* The following elements are set by Optimize(): */ BOOL fPushdownSort; /* Use ISAMSort() routines? */ BOOL fMSAccess; /* Is this the funny MSAccess */ /* query (see OPTIMIZE.C) ? */
/* The following elements are set by ExecuteQuery(): */ SDWORD RowCount; /* Number of rows */ SDWORD CurrentRow; /* Current row fetched */ STRINGIDX SortfileName; /* Name of the sortfile */ HFILE Sortfile; /* Sortfile */ BOOL ReturningDistinct; /* Does the sort file contain */ /* results of a DISTINCT op */ } select;
/* NODE_TYPE_INSERT */ struct { SQLNODEIDX Table; /* TABLE */ SQLNODEIDX Columns; /* COLUMNS */ SQLNODEIDX Values; /* VALUES, SELECT */ } insert;
/* NODE_TYPE_DELETE */ struct { SQLNODEIDX Table; /* TABLE */ SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */ /* NO_SQLNODE */ } delet;
/* NODE_TYPE_UPDATE */ struct { SQLNODEIDX Table; /* TABLE */ SQLNODEIDX Updatevalues; /* UPDATEVALUES */ SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */ /* NO_SQLNODE */ } update;
/* NODE_TYPE_PASSTHROUGH */
/* NODE_TYPE_TABLES */ struct { SQLNODEIDX Table; /* TABLE */ SQLNODEIDX Next; /* TABLES, NO_SQLNODE */ } tables;
/* NODE_TYPE_VALUES */ struct { SQLNODEIDX Value; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* NULL */ STRINGIDX Alias; /* Offset into the string area */ /* for the alias (only used */ /* for SELECT statements) */ SQLNODEIDX Next; /* VALUES, NO_SQLNODE */ } values;
/* NODE_TYPE_COLUMNS */ struct { SQLNODEIDX Column; /* COLUMN */ SQLNODEIDX Next; /* COLUMNS, NO_SQLNODE */ } columns;
/* NODE_TYPE_SORTCOLUMNS */ struct { SQLNODEIDX Column; /* COLUMN */ BOOL Descending; /* TRUE, FALSE */ SQLNODEIDX Next; /* SORTCOLUMNS, NO_SQLNODE */ } sortcolumns;
/* NODE_TYPE_GROUPBYCOLUMNS */ struct { SQLNODEIDX Column; /* COLUMN */ SQLNODEIDX Next; /* GROUPBYCOLUMNS, NO_SQLNODE */ } groupbycolumns;
/* NODE_TYPE_UPDATEVALUES */ struct { SQLNODEIDX Column; /* COLUMN */ SQLNODEIDX Value; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* NULL */ SQLNODEIDX Next; /* UPDATEVALUES, NO_SQLNODE */ } updatevalues;
/* NODE_TYPE_CREATECOLS */ struct { STRINGIDX Name; /* Offset into the string area */ /* for the name of the column */ STRINGIDX Type; /* Offset into the string area */ /* for the data type name */ UWORD Params; /* Number of create params */ UDWORD Param1; /* Value of param 1 (if any) */ UDWORD Param2; /* Value of param 2 (if any) */ SQLNODEIDX Next; /* CREATECOLS, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */ UWORD iSqlType; /* Index into SQLTypes[] of */ /* the type of the column */ } createcols;
/* NODE_TYPE_BOOLEAN */ struct { UWORD Operator; /* OP_NOT, OP_AND, or OP_OR */ SQLNODEIDX Left; /* BOOLEAN, COMPARISON, */ SQLNODEIDX Right; /* BOOLEAN, COMPARISON, */ /* NO_SQLNODE */ } boolean;
/* NODE_TYPE_COMPARISON */ struct { UWORD Operator; /* OP_EQ, OP_NE, OP_LE, OP_LT, */ /* OP_GE, OP_GT, OP_LIKE, */ /* OP_NOTLIKE, OP_IN, */ /* OP_NOTIN, OP_EXISTS */ UWORD SelectModifier; /* SELECT_NOTSELECT, */ /* SELECT_ALL, SELECT_ANY, */ /* SELECT_ONE, SELECT_EXISTS */ SQLNODEIDX Left; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* SELECT, NULL */ SQLNODEIDX Right; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* VALUES (for IN/NOTIN op), */ /* SELECT, NULL */
/* The following elements are set by Optimize(): */ UWORD fSelectivity; /* Selectivity the restriction */ SQLNODEIDX NextRestrict; /* COMPARISON, NO_SQLNODE */ /* The next restriction on the */ /* list of restrictions */ } comparison;
/* NODE_TYPE_ALGEBRAIC */ struct { UWORD Operator; /* OP_NEG, OP_PLUS, */ /* OP_MINUS, OP_TIMES, */ /* OP_DIVIDEDBY */ SQLNODEIDX Left; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* NULL */ SQLNODEIDX Right; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* NULL, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */ STRINGIDX Value; /* Value used to evaluate */ /* expressions */ STRINGIDX WorkBuffer1; /* Workbuffer used to evaluate */ /* NUMERIC multiply & divide */ STRINGIDX WorkBuffer2; /* Workbuffer used to evaluate */ /* NUMERIC divide */ STRINGIDX WorkBuffer3; /* Workbuffer used to evaluate */ /* NUMERIC divide */ UDWORD DistinctOffset; /* The offset the column is in */ /* in the sort DISTINCT */ /* record (one based). */ UDWORD DistinctLength; /* The length of the column in */ /* the sort DISTINCT record. */ SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */ /* UPDATE */ } algebraic;
/* NODE_TYPE_SCALAR */ struct { STRINGIDX Function; /* Name of the function */ SQLNODEIDX Arguments; /* VALUES, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */ UWORD Id; /* Scaler function id */ UWORD Interval; /* Interval for TIMESTAMPADD */ /* and TIMESTAMPDIFF */ STRINGIDX Value; /* Value used to evaluate */ /* expressions */ UDWORD DistinctOffset; /* The offset the column is in */ /* in the sort DISTINCT */ /* record (one based). */ UDWORD DistinctLength; /* The length of the column in */ /* the sort DISTINCT record. */ SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */ /* UPDATE */ } scalar;
/* NODE_TYPE_AGGREGATE */ struct { UWORD Operator; /* AGG_AVE, AGG_COUNT, */ /* AGG_MAX, AGG_MIN, AGG_SUM */ SQLNODEIDX Expression; /* COLUMN, ALGEBRAIC, SCALAR, */ /* AGGREGATE, NUMERIC, */ /* STRING, PARAMETER, USER, */ /* NULL */
/* The following elements are set by SemanticCheck(): */ STRINGIDX Value; /* Column value used to */ /* evaluate expressions */ UDWORD Offset; /* The offset the column is in */ /* in the sort record (one */ /* based). */ UDWORD Length; /* The length of the column in */ /* the sort record. */ UDWORD DistinctOffset; /* The offset the column is in */ /* in the sort DISTINCT */ /* record (one based). */ UDWORD DistinctLength; /* The length of the column in */ /* the sort DISTINCT record. */ SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */ /* UPDATE */ SQLNODEIDX Next; /* Rest of list of AGG */ /* functions for the query */ /* (this points to an */ /* AGGREGATE or NO_SQLNODE) */ /* The following elements are set at execution time: */ double Count; /* Number of records that had */ /* a non-NULL value */ } aggregate;
/* NODE_TYPE_TABLE */ struct { STRINGIDX Name; /* Offset into the string area */ /* for the name of the table */ STRINGIDX Qualifier; /* Offset into the string area */ /* for the qulaifier of the table */ STRINGIDX Alias; /* Offset into the string area */ /* for the name of the alias */ SQLNODEIDX OuterJoinFromTables;/* TABLES, NO_SQLNODE */ SQLNODEIDX OuterJoinPredicate; /* BOOLEAN, COMPARISON, */ /* NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */ LPISAMTABLEDEF Handle; /* Table handle */
/* The following elements are set by Optimize(): */ UWORD cRestrict; /* The number of Restrict nodes */ SQLNODEIDX Restrict; /* COMPARISON, NO_SQLNODE (if */ /* this points to a comparison */ /* node, the node is somewhere */ /* in the predicate, and is in */ /* the form: */ /* */ /* <column> <op> <constant> */ /* */ /* where <column> is some */ /* column of this table) */ UWORD Sortsequence; /* The relative position of */ /* this table when sorting */ UWORD Sortcount; /* The number of sort columns */ /* for this table */ SQLNODEIDX Sortcolumns; /* SORTCOLUMNS, NO_SQLNODE (the */ /* first in the list of sort */ /* columns for this table) */
/* The following elements are set at execution time: */ BOOL AllNull; /* Use NULL as value for all */ /* columns in current row */ BOOL Rewound; /* Is table positioned before */ /* first record? */ } table;
/* NODE_TYPE_COLUMN */ struct { STRINGIDX Tablealias; /* Offset into the string area */ /* for the name of the alias */ STRINGIDX Column; /* Offset into the string area */ /* for the name of the column */ STRINGIDX Qualifier; /* Offset into the string area */ /* for the name of the */ /* qualifier */ BOOL MatchedAlias; /* indicates if the TableAlias */ /* refers to a table name or an*/ /* alias. */ SQLNODEIDX TableIndex; /* index of table node to which*/ /* column belongs */ /* This renders the info above */ /* redundant. */
/* The following elements are set by SemanticCheck(): */ SQLNODEIDX Table; /* TABLE, NO_SQLNODE. Table */ /* of the column. If */ /* NO_SQLNODE, the column is */ /* in sort record. */ SWORD Id; /* Ordinal position of column */ STRINGIDX Value; /* Column value used to */ /* evaluate expressions */ BOOL InSortRecord; /* Is this column in the sort */ /* record? */ UDWORD Offset; /* The offset the column is in */ /* in the sort record (one */ /* based). */ UDWORD Length; /* The length of the column if */ /* it is in the sort record. */ UDWORD DistinctOffset; /* The offset the column is in */ /* in the sort DISTINCT */ /* record (one based). */ UDWORD DistinctLength; /* The length of the column in */ /* the sort DISTINCT record. */ SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */ /* UPDATE */ } column;
/* NODE_TYPE_STRING */ struct { STRINGIDX Value; /* Offset into the string area */ /* for the string */ } string;
/* NODE_TYPE_NUMERIC */ struct { double Value; STRINGIDX Numeric; } numeric;
/* NODE_TYPE_PARAMETER */ struct { UWORD Id; /* Ordinal position of parameter */ SQLNODEIDX Next; /* Rest of list of parameters for */ /* the query (this points to a */ /* PARAMETER or NO_SQLNODE) */
/* The following elements are set by SemanticCheck(): */ STRINGIDX Value; /* Parameter value used to */ /* evaluate expressions */ /* The following elements are set at execution time: */ BOOL AtExec; /* Value to be provided by */ /* ParamData()/PutData() */ } parameter;
/* NODE_TYPE_USER */ /* NODE_TYPE_NULL */
/* NODE_TYPE_DATE */ struct { DATE_STRUCT Value; } date;
/* NODE_TYPE_TIME */ struct { TIME_STRUCT Value; } time;
/* NODE_TYPE_TIMESTAMP */ struct { TIMESTAMP_STRUCT Value; } timestamp; } node; } SQLNODE, FAR * LPSQLNODE;
#define LPSQLTREE LPSQLNODE
#define NODE_TYPE_NONE 0
#define NODE_TYPE_ROOT 1
#define NODE_TYPE_CREATE 2
#define NODE_TYPE_DROP 3
#define NODE_TYPE_SELECT 4
#define NODE_TYPE_INSERT 5
#define NODE_TYPE_DELETE 6
#define NODE_TYPE_UPDATE 7
#define NODE_TYPE_PASSTHROUGH 8
#define NODE_TYPE_TABLES 9
#define NODE_TYPE_VALUES 10
#define NODE_TYPE_COLUMNS 11
#define NODE_TYPE_SORTCOLUMNS 12
#define NODE_TYPE_GROUPBYCOLUMNS 13
#define NODE_TYPE_UPDATEVALUES 14
#define NODE_TYPE_CREATECOLS 15
#define NODE_TYPE_BOOLEAN 16
#define NODE_TYPE_COMPARISON 17
#define NODE_TYPE_ALGEBRAIC 18
#define NODE_TYPE_AGGREGATE 19
#define NODE_TYPE_TABLE 20
#define NODE_TYPE_COLUMN 21
#define NODE_TYPE_STRING 22
#define NODE_TYPE_NUMERIC 23
#define NODE_TYPE_PARAMETER 24
#define NODE_TYPE_USER 25
#define NODE_TYPE_NULL 26
#define NODE_TYPE_DATE 27
#define NODE_TYPE_TIME 28
#define NODE_TYPE_TIMESTAMP 29
#define NODE_TYPE_CREATEINDEX 30
#define NODE_TYPE_DROPINDEX 31
#define NODE_TYPE_SCALAR 32
//Class used to re-convert WHERE predicate back into character string
class PredicateParser { private: LPSQLTREE FAR *lplpSql; LPISAMTABLEDEF lpISAMTableDef; BOOL fError; BOOL fSupportLIKEs;
//Generates string for a comparision expression
void GenerateComparisonString(char* lpLeftString, char* lpRightString, UWORD wOperator, UWORD wSelectModifier, char** lpOutputStr); //Generates string for a boolean expression
void GenerateBooleanString(char* lpLeftString, char* lpRightString, UWORD wOperator, char** lpOutputStr);
//Generates string for an aggregate expression
void GenerateAggregateString(char* lpLeftString, UWORD wOperator, char** lpOutputStr);
//Generates string for an algebraic expression
void GenerateAlgebraicString(char* lpLeftString, char* lpRightString, UWORD wOperator, char** lpOutputStr);
//Builds a column reference
void GenerateColumnRef(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
public:
//Generates WHERE predicate string from SQLNODETREE
void GeneratePredicateString(LPSQLNODE lpSqlNode, char** lpOutputStr, BOOL fIsSQL89 = TRUE);
//Builds GROUP BY statement
void GenerateGroupByString(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
//Builds ORDER BY statement
void GenerateOrderByString(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
// PredicateParser(LPSQLTREE FAR *lplpTheSql, SQLNODEIDX iPredicate)
// {lplpSql = lplpTheSql; Predicate = iPredicate;}
PredicateParser(LPSQLTREE FAR *lplpTheSql, LPISAMTABLEDEF lpISAMTblDef, BOOL fLIKEs = TRUE) {lplpSql = lplpTheSql; lpISAMTableDef = lpISAMTblDef; fError = FALSE; fSupportLIKEs = fLIKEs;} ~PredicateParser() {;} };
class PassthroughLookupTable { private: char tableAlias [MAX_QUALIFIER_NAME_LENGTH + 1]; char columnName [MAX_COLUMN_NAME_LENGTH + 1];
public:
BOOL SetTableAlias(char* tblAlias); char* GetTableAlias() {return tableAlias;}
BOOL SetColumnName(char* columName); char* GetColumnName() {return columnName;}
PassthroughLookupTable(); };
void TidyupPassthroughMap(CMapWordToPtr* passthroughMap);
class VirtualInstanceInfo { public:
//each element in the CMapStringToPtr is keyed on
//TableAlias.ColumnName
long cElements; //number of elements in this array
long cCycle; //value change cycle for instances
VirtualInstanceInfo(); ~VirtualInstanceInfo(); };
class VirtualInstanceManager { private:
CMapStringToPtr* virtualInfo;
char* ConstructKey(LPCTSTR TableAlias, LPCTSTR ColumnName);
IWbemClassObject* GetWbemObject(CBString& myTableAlias, IWbemClassObject* myInstance);
public:
long currentInstance; //zero-based index
long cNumberOfInstances;
void AddColumnInstance(LPCTSTR TableAlias, LPCTSTR ColumnName, VirtualInstanceInfo* col);
long GetArrayIndex(LPCTSTR TableAlias, LPCTSTR ColumnName, long instanceNum);
// void Testy();
void Load(CMapWordToPtr* passthroughMap, IWbemClassObject* myInstance);
BOOL GetVariantValue(CBString& myTableAlias, CBString& myColumnName, IWbemClassObject* myInstance, VARIANT FAR* myVal);
VirtualInstanceManager(); ~VirtualInstanceManager();
};
class TableColumnList { public: SQLNODEIDX idxColumnName; //column info
SQLNODEIDX idxTableAlias; //table alias for column
LPISAMTABLEDEF lpISAMTableDef; //table info
TableColumnList* Next; //Next item in list
TableColumnList(SQLNODEIDX idx, SQLNODEIDX idxAlias, LPISAMTABLEDEF lpTableDef) {idxColumnName = idx; idxTableAlias = idxAlias; lpISAMTableDef = lpTableDef; Next = NULL;} ~TableColumnList() {delete Next;} };
#define WQL_SINGLE_TABLE 1
#define WQL_MULTI_TABLE 2
class TableColumnInfo { private: LPSQLTREE FAR *lplpSql; LPSQLTREE FAR * lplpSqlNode; BOOL fIsValid; ULONG theMode; STRINGIDX idxTableQualifer; BOOL fDistinct; BOOL fHasScalarFunction; BOOL fIsSelectStar; BOOL m_aggregateExists;
void Analize(LPSQLNODE lpNode);
void StringConcat(char** resultString, char* myStr);
// void AddJoin(_bstr_t & tableList, SQLNODEIDX joinidx);
void AddJoinPredicate(char** tableList, SQLNODEIDX predicateidx);
public:
TableColumnList* lpList;
void BuildTableList(char** tableList, BOOL &fIsSQL89, SQLNODEIDX idx = NO_SQLNODE);
//Check if there is zero or one column/table entires in list
//This is used to check for COUNT(*)
BOOL IsZeroOrOneList();
//Have any aggregate functions been detected
BOOL HasAggregateFunctions() {return m_aggregateExists;}
//Is SELECT DISTINCT select-list FROM .....
BOOL IsDistinct() {return fDistinct;}
//Is SELECT * FROM ...
BOOL IsSelectStar() {return fIsSelectStar;}
//Was table column info parsed successfully
BOOL IsValid() {return fIsValid;}
//Indicate if query contains scalar function
BOOL HasScalarFunction() {return fHasScalarFunction;}
//Builds a select list for the chosen table
void BuildSelectList(LPISAMTABLEDEF lpTableDef, char** lpSelectListStr, BOOL fIsSQL89 = TRUE, CMapWordToPtr** ppPassthroughMap = NULL);
//Builds whole WQL statement
void BuildFullWQL(char** lpWQLStr, CMapWordToPtr** ppPassthroughMap = NULL);
STRINGIDX GetTableQualifier() {return idxTableQualifer;}
//Indicates if at least one column in the specified table
//is refernced in the SQL statement
BOOL IsTableReferenced(LPISAMTABLEDEF lpTableDef);
TableColumnInfo(LPSQLTREE FAR *lplpTheSql, LPSQLTREE FAR * lpSqlN, ULONG mode = WQL_SINGLE_TABLE); ~TableColumnInfo() {delete lpList;}
};
#define DATETIME_FORMAT_LEN 21
#define DATETIME_DATE_LEN 8
#define DATETIME_TIME_LEN 6
#define DATETIME_YEAR_LEN 4
#define DATETIME_MONTH_LEN 2
#define DATETIME_DAY_LEN 2
#define DATETIME_HOUR_LEN 2
#define DATETIME_MIN_LEN 2
#define DATETIME_SEC_LEN 2
#define DATETIME_MICROSEC_LEN 6
class DateTimeParser { private: BOOL fIsValid; BOOL fValidDate; BOOL fValidTime;
BOOL fIsaTimestamp; BOOL fIsaDate; BOOL fIsaTime;
ULONG m_year; ULONG m_month; ULONG m_day;
ULONG m_hour; ULONG m_min; ULONG m_sec;
ULONG m_microSec;
char dateTimeBuff[DATETIME_FORMAT_LEN + 1]; char tempBuff[DATETIME_MICROSEC_LEN + 1];
BOOL IsNumber(char bChar); void FetchField(char* lpStr, WORD wFieldLen, ULONG &wValue); void ValidateFields(); public:
BOOL IsValid() {return fIsValid;}
BOOL IsTimestamp() {return fIsaTimestamp;} BOOL IsDate() {return fIsaDate;} BOOL IsTime() {return fIsaTime;}
ULONG GetYear() {return m_year;} ULONG GetMonth() {return m_month;} ULONG GetDay() {return m_day;} ULONG GetHour() {return m_hour;} ULONG GetMin() {return m_min;} ULONG GetSec() {return m_sec;} ULONG GetMicroSec() {return m_microSec;}
DateTimeParser(BSTR dateTimeStr); ~DateTimeParser() {;} };
/***************************************************************************/ #define ToNode(lpSql, idx) (&((lpSql)[idx]))
#define ToString(lpSql, idx) (&((lpSql)->node.root.lpStringArea[idx]))
/***************************************************************************/ RETCODE INTFUNC Parse(LPSTMT, LPISAM, LPUSTR, SDWORD, LPSQLTREE FAR *); SQLNODEIDX INTFUNC AllocateNode(LPSQLTREE FAR *, UWORD); STRINGIDX INTFUNC AllocateSpace(LPSQLTREE FAR *, SWORD); STRINGIDX INTFUNC AllocateString(LPSQLTREE FAR *, LPUSTR); void INTFUNC FreeTree(LPSQLTREE); /***************************************************************************/
|